소스 검색

qwen lora sft 训练流程及数据处理

fangjiasheng 1 주 전
부모
커밋
62f0f46b2a
28개의 변경된 파일8248개의 추가작업 그리고 0개의 파일을 삭제
  1. 1 0
      qwen_lora/command_files/gguf_model_to_q4_k_m.txt
  2. 1 0
      qwen_lora/command_files/start_infer_llama_cpu.txt
  3. 1 0
      qwen_lora/command_files/start_infer_llama_gpu.txt
  4. 4 0
      qwen_lora/command_files/train_to_ollama.txt
  5. 604 0
      qwen_lora/compare_result.py
  6. 216 0
      qwen_lora/compare_utils.py
  7. BIN
      qwen_lora/data_files/260403_ai_人工标注_招标人表达_3_再人工.xlsx
  8. BIN
      qwen_lora/data_files/260403_ai_人工标注_招标人表达_3_再人工_html.xlsx
  9. BIN
      qwen_lora/data_files/260403_ai_人工标注_招标人表达_3_再人工_json.xlsx
  10. BIN
      qwen_lora/data_files/df_train.xlsx
  11. BIN
      qwen_lora/data_files/df_train_doubao.xlsx
  12. 1 0
      qwen_lora/data_files/document_tmp_has_ai_no_attachment_260327_limit.csv
  13. 2115 0
      qwen_lora/data_files/export_ai_260327_2.csv
  14. 1187 0
      qwen_lora/data_files/export_ai_260417_saimofei_html.csv
  15. BIN
      qwen_lora/data_files/export_ai_260506_doubao.xlsx
  16. BIN
      qwen_lora/data_files/export_entity_260414_0.8B_prefix_only_tenderee_all.xlsx
  17. BIN
      qwen_lora/data_files/招标人_中标人_标注_260421 (1).xlsx
  18. 18 0
      qwen_lora/data_files/招标人_中标人_标注_260421_html.csv
  19. 1050 0
      qwen_lora/data_files/招标人_中标人_标注_260421_tenderee_win_2.csv
  20. BIN
      qwen_lora/data_files/招标人标注_260414.xlsx
  21. BIN
      qwen_lora/data_files/赛默飞-样例数据.xlsx
  22. 205 0
      qwen_lora/finetune_sft.py
  23. 1950 0
      qwen_lora/get_data.py
  24. 458 0
      qwen_lora/infer_files.py
  25. 161 0
      qwen_lora/infer_llama.py
  26. 121 0
      qwen_lora/infer_ollama.py
  27. 121 0
      qwen_lora/load_data.py
  28. 34 0
      qwen_lora/merge_model.py

+ 1 - 0
qwen_lora/command_files/gguf_model_to_q4_k_m.txt

@@ -0,0 +1 @@
+/data2/fangjiasheng/llama.cpp/build/bin/llama-quantize /data2/fangjiasheng/qwen_lora/qwen_0.8B_lora_bidding_kg/model/gguf_model/qwen-bidding-f16.gguf /data2/fangjiasheng/qwen_lora/qwen_0.8B_lora_bidding_kg/model/gguf_model/qwen-bidding-v1-q4.gguf Q4_K_M

+ 1 - 0
qwen_lora/command_files/start_infer_llama_cpu.txt

@@ -0,0 +1 @@
+CUDA_VISIBLE_DEVICES="" /data2/fangjiasheng/llama.cpp/build/bin/llama-server -m /data2/fangjiasheng/qwen_lora/qwen_0.8B_lora_bidding_kg/model/gguf_model/qwen-bidding-f16-16K.gguf   -c 16384   -t 4   --host 0.0.0.0   --port 8765   --temp 0   --repeat-penalty 1.1 -ngl 0

+ 1 - 0
qwen_lora/command_files/start_infer_llama_gpu.txt

@@ -0,0 +1 @@
+CUDA_VISIBLE_DEVICES="0" /data2/fangjiasheng/llama.cpp/build/bin/llama-server -m /data2/fangjiasheng/qwen_lora/qwen_0.8B_lora_bidding_kg/model/gguf_model/qwen-f16.gguf   -c 16384   -t 4   --host 0.0.0.0   --port 8765   --temp 0   --repeat-penalty 1.1 -ngl 99

+ 4 - 0
qwen_lora/command_files/train_to_ollama.txt

@@ -0,0 +1,4 @@
+micromamba activate py310-mamba
+python merge_model_unsloth.py
+python /data2/fangjiasheng/llama.cpp/convert_hf_to_gguf.py /data2/fangjiasheng/qwen_lora/qwen_0.8B_lora_bidding_kg/model/qwen-merged-model-16K/ --outfile /data2/fangjiasheng/qwen_lora/qwen_0.8B_lora_bidding_kg/model/gguf_model/qwen-bidding-f16-16K-5.gguf --outtype f16
+ollama create bidding-qwen-0.8B-lora-16k:latest -f Modelfile

+ 604 - 0
qwen_lora/compare_result.py

@@ -0,0 +1,604 @@
+import json
+import re
+import traceback
+from glob import glob
+
+import pandas as pd
+from bs4 import BeautifulSoup
+from json_repair import repair_json, json_repair
+from get_data import psv_to_dict, psv_to_dict_prefix
+from compare_utils import compare_products
+
+
+def compare_extract_csv():
+    df_tenderee = pd.read_csv(r'D:\BIDI_DOC\比地_文档\export_ai_260323_2_tenderee.csv')
+    df1 = pd.read_excel(r'D:\BIDI_DOC\比地_文档\export_ai_260323_1.xlsx')
+    df2 = pd.read_excel(r'D:\BIDI_DOC\比地_文档\export_ai_260323_3.xlsx')
+    # df3 = pd.read_excel(r'D:\BIDI_DOC\比地_文档\export_ai_260323_3_lora_2.xlsx')
+    # df3 = pd.read_excel(r'D:\BIDI_DOC\比地_文档\export_ai_260331_lora.xlsx')
+    # df3 = pd.read_excel(r'D:\BIDI_DOC\比地_文档\export_ai_260401_lora-r64.xlsx')
+    # df3 = pd.read_excel(r'D:\BIDI_DOC\比地_文档\export_ai_260401_lora_2B.xlsx')
+    # df3 = pd.read_excel(r'D:\BIDI_DOC\比地_文档\export_ai_260402_lora_2B.xlsx')
+    # df3 = pd.read_excel(r'D:\BIDI_DOC\比地_文档\export_ai_260407_0.8B.xlsx')
+    # df3 = pd.read_excel(r'D:\BIDI_DOC\比地_文档\export_ai_260408_0.8B.xlsx')
+    # df3 = pd.read_excel(r'D:\BIDI_DOC\比地_文档\export_ai_260409_0.8B.xlsx')
+    # df3 = pd.read_excel(r'D:\BIDI_DOC\比地_文档\export_ai_260413_0.8B.xlsx')
+    df3 = pd.read_excel(r'D:\BIDI_DOC\比地_文档\export_ai_260423_0.8B_prefix_all.xlsx')
+
+    tenderee_data_list = df_tenderee.astype(object).where(pd.notnull(df_tenderee), None).values.tolist()
+    data_list1 = df1.astype(object).where(pd.notnull(df1), None).values.tolist()
+    data_list2 = df2.astype(object).where(pd.notnull(df2), None).values.tolist()
+    data_list3 = df3.astype(object).where(pd.notnull(df3), None).values.tolist()
+
+    tenderee_data_dict = {int(x[0]): x[1] for x in tenderee_data_list}
+    data_dict1 = {int(x[0]): x[1] for x in data_list1}
+    data_dict2 = {int(x[0]): x[1] for x in data_list2}
+    data_dict3 = {int(x[0]): psv_to_dict(x[1]) for x in data_list3}
+
+    for docid, v_dict in data_dict3.items():
+        v1 = v_dict.get('招标信息')
+        v2 = v_dict.get('招标人联系方式')
+        if v1 is None or v2 is None:
+            continue
+        v1 = v1[0]
+        if not v1:
+            continue
+        v1['招标人联系方式'] = v2
+        v_dict['招标信息'] = v1
+        data_dict3[docid] = v_dict
+
+    for docid, v_dict in data_dict3.items():
+        data_dict3[docid] = json.dumps(v_dict, ensure_ascii=False)
+
+    # print('data_dict3', data_dict3.get(751300501))
+
+    cols = ['招标信息', '中标信息', '产品信息']
+
+    result_list = []
+    tenderee_match_cnt = 0
+    tenderee_match_empty_cnt = 0
+    real_tenderee_match_cnt1 = 0
+    real_tenderee_match_cnt2 = 0
+    win_tenderer_match_cnt = 0
+    agency_match_cnt = 0
+    all_product_weight_score = 0
+    all_product_complete_score = 0
+    all_product_cnt_score = 0
+    for docid, data1 in data_dict1.items():
+        data2 = data_dict2.get(docid, '{}')
+        data3 = data_dict3.get(docid, '{}')
+
+        # if len(re.findall('}]}', data2)) != 2:
+        #     data2 = re.sub('}]', '}]}', data2, count=1)
+        # if len(re.findall('}]}', data3)) != 2:
+        #     data3 = re.sub('}]', '}]}', data3, count=1)
+
+        # if len(data1) >= 1000:
+        #     data1 = '{}'
+        # if len(data2) >= 1000:
+        #     data2 = '{}'
+        # if len(data3) >= 1000:
+        #     data3 = '{}'
+
+        # if len(data1) >= 1000:
+        #     extract_json1 = '{}'
+        # else:
+        extract_json1 = repair_json(data1)
+        if len(data2) >= 1000:
+            extract_json2 = '{}'
+        else:
+            extract_json2 = repair_json(data2)
+        # if len(data3) >= 1000:
+        #     extract_json3 = '{}'
+        # else:
+        #     extract_json3 = repair_json(data3)
+        # print('data2', data2)
+        extract_json3 = repair_json(data3)
+
+        extract_json1 = json_repair.loads(extract_json1)
+        extract_json2 = json_repair.loads(extract_json2)
+        extract_json3 = json_repair.loads(extract_json3)
+        # print('extract_json2', extract_json2)
+
+        if type(extract_json1) != dict:
+            extract_json1 = {}
+        if type(extract_json2) != dict:
+            extract_json2 = {}
+        if type(extract_json3) != dict:
+            extract_json3 = {}
+
+        col_match_list = []
+        for col in cols:
+            str1 = json.dumps(extract_json1.get(col, ""), ensure_ascii=False)
+            str2 = json.dumps(extract_json2.get(col, ""), ensure_ascii=False)
+            str3 = json.dumps(extract_json3.get(col, ""), ensure_ascii=False)
+
+            if str1 != str3:
+                col_match_list += [str1, str2, str3, 0]
+            else:
+                col_match_list += [str1, str2, str3, 1]
+
+        tenderee_real = tenderee_data_dict.get(docid)
+        tenderee1 = extract_json1.get('招标信息', {}).get('招标人名称', "")
+        try:
+            tenderee3 = extract_json3.get('招标信息', {}).get('招标人名称', "")
+        except:
+            print('no 招标信息 招标人名称 extract_json3', extract_json3)
+            # raise
+            tenderee3 = ''
+        if re.sub(' ', '', tenderee1) == re.sub(' ', '', tenderee3):
+            tenderee_match_cnt += 1
+            if not tenderee1:
+                tenderee_match_empty_cnt += 1
+
+        if tenderee1 == tenderee_real:
+            real_tenderee_match_cnt1 += 1
+        if tenderee3 == tenderee_real:
+            real_tenderee_match_cnt2 += 1
+
+        win_tenderer1 = [x.get('中标人名称', "") for x in extract_json1.get('中标信息', [])]
+        win_tenderer1 = list(set(win_tenderer1))
+        win_tenderer1.sort(key=lambda x: x)
+        win_tenderer1 = ','.join(win_tenderer1)
+        try:
+            win_tenderer3 = [x.get('中标人名称', "") for x in extract_json3.get('中标信息', [])]
+            win_tenderer3 = list(set(win_tenderer3))
+            win_tenderer3.sort(key=lambda x: x)
+            win_tenderer3 = ','.join(win_tenderer3)
+        except:
+            print('no 中标信息 中标人名称 extract_json3', extract_json3)
+            # raise
+            win_tenderer3 = ''
+
+        if win_tenderer1 == win_tenderer3:
+            print('win_tenderer1 == win_tenderer3', win_tenderer1, win_tenderer3)
+            win_tenderer_match_cnt += 1
+
+        agency1 = extract_json1.get('招标信息', {}).get('代理人名称', "")
+        try:
+            agency3 = extract_json3.get('招标信息', {}).get('代理人名称', "")
+        except:
+            print('no 招标信息 中标人名称 extract_json3', extract_json3)
+            # raise
+            agency3 = ''
+
+        if agency1 == agency3:
+            agency_match_cnt += 1
+
+        # 计算products匹配率
+        products1 = extract_json1.get('产品信息')
+        products3 = extract_json3.get('产品信息')
+        # print('products3', products3)
+        product_weight_score, product_complete_score, product_cnt_score = compare_products(products1, products3)
+        all_product_weight_score += product_weight_score
+        all_product_complete_score += product_complete_score
+        all_product_cnt_score += product_cnt_score
+
+        result_list.append(
+            [docid, data1, data2, data3] +
+            col_match_list +
+            [tenderee1, tenderee3, tenderee_real] +
+            [str(tenderee1==tenderee3), str(tenderee1==tenderee_real), str(tenderee3==tenderee_real)] +
+            [win_tenderer1, win_tenderer3, str(win_tenderer1==win_tenderer3)] +
+            [agency1, agency3, str(agency1==agency3)]
+        )
+
+    df_new = pd.DataFrame(result_list)
+    df_new.columns = ['docid',
+                      'doubao', 'qwen', 'qwen-lora',
+                      '招标信息1', '招标信息2', '招标信息3', '招标信息相同',
+                      '中标信息1', '中标信息2', '中标信息3', '中标信息相同',
+                      '产品信息1', '产品信息2', '产品信息3', '产品信息相同',
+                      'tenderee_doubao', 'tenderee_qwen', '线上_tenderee',
+                      'doubao_qwen_相同', 'doubao_线上_相同', 'qwen_线上相同',
+                      'win_doubao', 'win_qwen', 'doubao_qwen_相同',
+                      'agency_doubao', 'agency_qwen', 'doubao_qwen_相同',
+                      ]
+
+    df_new.to_excel(r'D:\BIDI_DOC\比地_文档\export_ai_260423_compare_doubao_0.8B_prefix.xlsx', index=False)
+    all_cnt = len(data_dict1)
+    print('tenderee_match_cnt', tenderee_match_cnt, tenderee_match_cnt/all_cnt, 'tenderee_match_empty_cnt', tenderee_match_empty_cnt)
+    print('real_tenderee_match_cnt1', real_tenderee_match_cnt1, real_tenderee_match_cnt1/all_cnt)
+    print('real_tenderee_match_cnt2', real_tenderee_match_cnt2, real_tenderee_match_cnt2/all_cnt)
+    print('win_tenderer_match_cnt', win_tenderer_match_cnt, win_tenderer_match_cnt/all_cnt)
+    print('agency_match_cnt', agency_match_cnt, agency_match_cnt/all_cnt)
+    print('product_weight_score', all_product_weight_score / all_cnt)
+    print('product_complete_score', all_product_complete_score / all_cnt)
+    print('product_cnt_score', all_product_cnt_score / all_cnt)
+
+
+def compare_extract_csv_prefix():
+    # df_tenderee = pd.read_csv(r'D:\BIDI_DOC\比地_文档\export_ai_260323_2_tenderee.csv')
+
+    df_tenderee1 = pd.read_excel(r'D:\BIDI_DOC\比地_文档\招标人标注_260414.xlsx', sheet_name=0)
+    df_tenderee2 = pd.read_excel(r'D:\BIDI_DOC\比地_文档\招标人标注_260414.xlsx', sheet_name=1)
+    df_tenderee3 = pd.read_excel(r'D:\BIDI_DOC\比地_文档\招标人标注_260414.xlsx', sheet_name=2)
+    df_tenderee = pd.concat([df_tenderee1, df_tenderee2, df_tenderee3], ignore_index=True)
+
+    df1 = pd.read_excel(r'D:\BIDI_DOC\比地_文档\export_ai_260323_1.xlsx')
+    df2 = pd.read_excel(r'D:\BIDI_DOC\比地_文档\export_ai_260323_3.xlsx')
+    # df3 = pd.read_excel(r'D:\BIDI_DOC\比地_文档\export_ai_260413_0.8B_prefix_only_tenderee.xlsx')
+    df3 = pd.read_excel(r'D:\BIDI_DOC\比地_文档\export_ai_260413_0.8B_prefix_only_tenderee_all.xlsx')
+
+    tenderee_data_list = df_tenderee.astype(object).where(pd.notnull(df_tenderee), None).values.tolist()
+    data_list1 = df1.astype(object).where(pd.notnull(df1), None).values.tolist()
+    data_list2 = df2.astype(object).where(pd.notnull(df2), None).values.tolist()
+    data_list3 = df3.astype(object).where(pd.notnull(df3), None).values.tolist()
+
+    tenderee_data_dict = {int(x[0]): x[1] for x in tenderee_data_list}
+
+    data_dict1 = {int(x[0]): x[1] for x in data_list1}
+    data_dict2 = {int(x[0]): x[1] for x in data_list2}
+    data_dict3 = {int(x[0]): psv_to_dict_prefix(x[1]) for x in data_list3}
+
+    for docid, v_dict in data_dict3.items():
+        data_dict3[docid] = json.dumps(v_dict, ensure_ascii=False)
+
+    cols = ['招标信息', '中标信息', '产品信息']
+
+    result_list = []
+    tenderee_match_cnt = 0
+    tenderee_match_empty_cnt = 0
+    real_tenderee_match_cnt1 = 0
+    real_tenderee_match_cnt2 = 0
+    for docid, tenderee_data in tenderee_data_dict.items():
+        data1 = data_dict1.get(docid, '{}')
+        data2 = data_dict2.get(docid, '{}')
+        data3 = data_dict3.get(docid, '{}')
+
+        extract_json1 = repair_json(data1)
+        if len(data2) >= 1000:
+            extract_json2 = '{}'
+        else:
+            extract_json2 = repair_json(data2)
+        extract_json3 = repair_json(data3)
+
+        extract_json1 = json_repair.loads(extract_json1)
+        extract_json2 = json_repair.loads(extract_json2)
+        extract_json3 = json_repair.loads(extract_json3)
+
+        if type(extract_json1) != dict:
+            extract_json1 = {}
+        if type(extract_json2) != dict:
+            extract_json2 = {}
+        if type(extract_json3) != dict:
+            extract_json3 = {}
+
+        col_match_list = []
+        for col in cols:
+            str1 = json.dumps(extract_json1.get(col, ""), ensure_ascii=False)
+            str2 = json.dumps(extract_json2.get(col, ""), ensure_ascii=False)
+            str3 = json.dumps(extract_json3.get(col, ""), ensure_ascii=False)
+
+            if str1 != str3:
+                col_match_list += [str1, str2, str3, 0]
+            else:
+                col_match_list += [str1, str2, str3, 1]
+
+        tenderee_real = tenderee_data_dict.get(docid)
+        if tenderee_real in ['文中无招标人', '-']:
+            tenderee_real = ''
+        tenderee1 = extract_json1.get('招标信息', {}).get('招标人名称', "")
+        try:
+            tenderee3 = extract_json3.get('招标信息', {}).get('招标人名称', "")
+        except:
+            print('no 招标信息 招标人名称 extract_json3', extract_json3)
+            # raise
+            tenderee3 = ''
+        if tenderee1 in ['文中无招标人', '-']:
+            tenderee1 = ''
+        if tenderee3 in ['文中无招标人', '-']:
+            tenderee3 = ''
+
+        if re.sub(' ', '', tenderee1) == re.sub(' ', '', tenderee3):
+            tenderee_match_cnt += 1
+            if not tenderee1:
+                tenderee_match_empty_cnt += 1
+
+        if tenderee1 == tenderee_real:
+            real_tenderee_match_cnt1 += 1
+        if tenderee3 == tenderee_real:
+            real_tenderee_match_cnt2 += 1
+
+        result_list.append(
+            [docid, data1, data2, data3] +
+            col_match_list +
+            [tenderee1, tenderee3, tenderee_real] +
+            [str(tenderee1==tenderee3), str(tenderee1==tenderee_real), str(tenderee3==tenderee_real)]
+        )
+
+    df_new = pd.DataFrame(result_list)
+    df_new.columns = ['docid', 'doubao', 'qwen', 'qwen-lora',
+                      '招标信息1', '招标信息2', '招标信息3', '招标信息相同',
+                      '中标信息1', '中标信息2', '中标信息3', '中标信息相同',
+                      '产品信息1', '产品信息2', '产品信息3', '产品信息相同',
+                      'tenderee_doubao', 'tenderee_qwen', '线上_tenderee',
+                      'doubao_qwen_相同', 'doubao_线上_相同', 'qwen_线上相同',
+                      ]
+
+    df_new.to_excel(r'D:\BIDI_DOC\比地_文档\export_ai_260414_compare_only_tenderee_labeled.xlsx', index=False)
+    print('tenderee_match_cnt', tenderee_match_cnt, 'tenderee_match_empty_cnt', tenderee_match_empty_cnt)
+    print('real_tenderee_match_cnt1', real_tenderee_match_cnt1, real_tenderee_match_cnt1/len(tenderee_data_dict))
+    print('real_tenderee_match_cnt2', real_tenderee_match_cnt2, real_tenderee_match_cnt2/len(tenderee_data_dict))
+    print('len(tenderee_data_dict)', len(tenderee_data_dict))
+
+
+def compare_extract_csv_prefix2():
+    file_path1 = r'C:\Users\Administrator\Downloads\招标人_中标人_标注_260421 (1).xlsx'
+    file_path2 = r'D:\BIDI_DOC\比地_文档\export_ai_260506_doubao.xlsx'
+    file_path3 = r'D:\BIDI_DOC\比地_文档\export_ai_260506_0.8B_prefix_all.xlsx'
+    file_path4 = r'D:\BIDI_DOC\比地_文档\招标人_中标人_标注_260421_tenderee_win_2.csv'
+
+    data_list1 = []
+    for sheet_no in range(0, 7):
+        df1 = pd.read_excel(file_path1, sheet_name=sheet_no)
+        data_list1 += df1.astype(object).where(pd.notnull(df1), None).values.tolist()
+
+    print('len(data_list1)', len(data_list1), data_list1[0])
+
+    df2 = pd.read_excel(file_path2)
+    df3 = pd.read_excel(file_path3)
+    df4 = pd.read_csv(file_path4)
+
+    data_list2 = df2.astype(object).where(pd.notnull(df2), None).values.tolist()
+    data_list3 = df3.astype(object).where(pd.notnull(df3), None).values.tolist()
+    data_list4 = df4.astype(object).where(pd.notnull(df4), None).values.tolist()
+
+    data_dict_label = {int(x[0]): {'招标信息': {'招标人名称': x[3]}, '中标信息': [{'中标人名称': x[4]}]} for x in data_list1}
+    data_dict_doubao = {int(x[0]): x[2] for x in data_list2}
+    data_dict_qwen = {int(x[0]): psv_to_dict(x[1]) for x in data_list3}
+    data_dict_online = {int(x[0]): {'招标信息': {'招标人名称': x[1]}, '中标信息': [{'中标人名称': x[2]}]} for x in data_list4}
+
+    for docid, v_dict in data_dict_qwen.items():
+        data_dict_qwen[docid] = json.dumps(v_dict, ensure_ascii=False)
+    for docid, v_dict in data_dict_label.items():
+        data_dict_label[docid] = json.dumps(v_dict, ensure_ascii=False)
+    for docid, v_dict in data_dict_online.items():
+        data_dict_online[docid] = json.dumps(v_dict, ensure_ascii=False)
+
+    cols = ['招标信息', '中标信息', '产品信息']
+
+    result_list = []
+    tenderee_match_cnt = 0
+    tenderee_match_empty_cnt = 0
+    real_tenderee_match_cnt1 = 0
+    real_tenderee_match_cnt2 = 0
+    real_tenderee_match_cnt3 = 0
+    win_match_cnt = 0
+    win_match_empty_cnt = 0
+    real_win_match_cnt1 = 0
+    real_win_match_cnt2 = 0
+    real_win_match_cnt3 = 0
+    for docid, label_data in data_dict_label.items():
+        data1 = data_dict_label.get(docid, '{}')
+        data2 = data_dict_doubao.get(docid, '{}')
+        data3 = data_dict_qwen.get(docid, '{}')
+        data4 = data_dict_online.get(docid, '{}')
+
+        extract_json1 = repair_json(data1)
+        if len(data2) >= 1000:
+            extract_json2 = '{}'
+        else:
+            extract_json2 = repair_json(data2)
+        extract_json3 = repair_json(data3)
+        extract_json4 = repair_json(data4)
+
+        extract_json1 = json_repair.loads(extract_json1)
+        extract_json2 = json_repair.loads(extract_json2)
+        extract_json3 = json_repair.loads(extract_json3)
+        extract_json4 = json_repair.loads(extract_json4)
+
+        if type(extract_json1) != dict:
+            extract_json1 = {}
+        if type(extract_json2) != dict:
+            extract_json2 = {}
+        if type(extract_json3) != dict:
+            extract_json3 = {}
+        if type(extract_json4) != dict:
+            extract_json4 = {}
+
+        col_match_list = []
+        for col in cols:
+            str1 = json.dumps(extract_json1.get(col, ""), ensure_ascii=False)
+            str2 = json.dumps(extract_json2.get(col, ""), ensure_ascii=False)
+            str3 = json.dumps(extract_json3.get(col, ""), ensure_ascii=False)
+
+            if str1 != str3:
+                col_match_list += [str1, str2, str3, 0]
+            else:
+                col_match_list += [str1, str2, str3, 1]
+
+        tenderee_label = extract_json1.get('招标信息', []).get('招标人名称', "")
+        try:
+            tenderee_doubao = extract_json2.get('招标信息', {}).get('招标人名称', "")
+        except:
+            print('no 招标信息 招标人名称 extract_json2', extract_json2)
+            tenderee_doubao = ''
+        try:
+            tenderee_qwen = extract_json3.get('招标信息', [])
+            if tenderee_qwen:
+                tenderee_qwen = tenderee_qwen[0].get('招标人名称', "")
+            else:
+                tenderee_qwen = ''
+        except:
+            print('no 招标信息 招标人名称 extract_json3', type(extract_json3), extract_json3)
+            traceback.print_exc()
+            tenderee_qwen = ''
+        tenderee_online = extract_json4.get('招标信息', []).get('招标人名称', "")
+
+        if tenderee_label in ['文中无招标人', '-', '无', None]:
+            tenderee_label = ''
+        if tenderee_doubao in ['文中无招标人', '-', '无', None] or type(tenderee_doubao) != str:
+            tenderee_doubao = ''
+        if tenderee_qwen in ['文中无招标人', '-', '无', None] or type(tenderee_qwen) != str:
+            tenderee_qwen = ''
+        if tenderee_online in ['文中无招标人', '-', '无', None] or type(tenderee_online) != str:
+            tenderee_online = ''
+
+        # print('tenderee_doubao', tenderee_doubao)
+        if re.sub(' ', '', tenderee_doubao) == re.sub(' ', '', tenderee_qwen):
+            tenderee_match_cnt += 1
+            if not tenderee_doubao:
+                tenderee_match_empty_cnt += 1
+
+        if tenderee_doubao == tenderee_label:
+            real_tenderee_match_cnt1 += 1
+        if tenderee_qwen == tenderee_label:
+            real_tenderee_match_cnt2 += 1
+        if tenderee_online == tenderee_label:
+            real_tenderee_match_cnt3 += 1
+
+        win_label = extract_json1.get('中标信息', [])
+        if win_label:
+            win_label = win_label[0].get('中标人名称', "")
+        else:
+            win_label = ''
+        win_doubao = extract_json2.get('中标信息', [])
+        if win_doubao:
+            win_doubao = win_doubao[0].get('中标人名称', "")
+        else:
+            win_doubao = ''
+        try:
+            win_qwen = extract_json3.get('中标信息', [])
+            if win_qwen:
+                win_qwen = win_qwen[0].get('中标人名称', "")
+            else:
+                win_qwen = ''
+
+        except:
+            print('no 中标人名称 extract_json3', extract_json3)
+            win_qwen = ''
+
+        win_online = extract_json4.get('中标信息', [])
+        if win_online:
+            win_online = win_online[0].get('中标人名称', "")
+        else:
+            win_online = ''
+
+        if win_label in ['文中无招标人', '-', '无', None]:
+            win_label = ''
+        if win_doubao in ['文中无招标人', '-', '无', None]:
+            win_doubao = ''
+        if win_qwen in ['文中无招标人', '-', '无', None]:
+            win_qwen = ''
+        if win_online in ['文中无招标人', '-', '无', None]:
+            win_online = ''
+
+        # print('win_doubao', win_doubao, win_qwen)
+        if re.sub(' ', '', win_doubao) == re.sub(' ', '', win_qwen):
+            win_match_cnt += 1
+            if not win_doubao:
+                win_match_empty_cnt += 1
+
+        if win_doubao == win_label:
+            real_win_match_cnt1 += 1
+        if win_qwen == win_label:
+            real_win_match_cnt2 += 1
+        if win_online == win_label:
+            real_win_match_cnt3 += 1
+
+        result_list.append(
+            [docid, data1, data2, data3] +
+            col_match_list +
+            [tenderee_doubao, tenderee_qwen, tenderee_online, tenderee_label] +
+            [str(tenderee_doubao==tenderee_qwen), str(tenderee_doubao==tenderee_label), str(tenderee_online==tenderee_label), str(tenderee_qwen==tenderee_label)] +
+            [win_doubao, win_qwen, win_online, win_label] +
+            [str(win_doubao==win_qwen), str(win_doubao==win_label), str(win_online==win_label), str(win_qwen==win_label)]
+        )
+
+    df_new = pd.DataFrame(result_list)
+    df_new.columns = ['docid', 'doubao', 'qwen', 'qwen-lora',
+                      '招标信息1', '招标信息2', '招标信息3', '招标信息相同',
+                      '中标信息1', '中标信息2', '中标信息3', '中标信息相同',
+                      '产品信息1', '产品信息2', '产品信息3', '产品信息相同',
+                      'tenderee_doubao', 'tenderee_qwen', 'tenderee_online', 'tenderee_label',
+                      'doubao_qwen_相同', 'doubao_标注_相同', '线上_标注_相同', 'qwen_标注_相同',
+                      'win_doubao', 'win_qwen', 'win_online', 'win_label',
+                      'doubao_qwen_相同', 'doubao_标注_相同', '线上_标注_相同', 'qwen_标注_相同',
+                      ]
+
+    df_new.to_excel(r'D:\BIDI_DOC\比地_文档\export_ai_260506_compare_labeled.xlsx', index=False)
+    print('tenderee_match_cnt', tenderee_match_cnt, 'tenderee_match_empty_cnt', tenderee_match_empty_cnt)
+    print('real_tenderee_match_cnt1', real_tenderee_match_cnt1, real_tenderee_match_cnt1/len(data_dict_label))
+    print('real_tenderee_match_cnt2', real_tenderee_match_cnt2, real_tenderee_match_cnt2/len(data_dict_label))
+    print('real_tenderee_match_cnt3', real_tenderee_match_cnt3, real_tenderee_match_cnt3/len(data_dict_label))
+
+    # print('len(tenderee_data_dict)', len(tenderee_data_dict))
+    print('win_match_cnt', win_match_cnt, 'win_match_empty_cnt', win_match_empty_cnt)
+    print('real_win_match_cnt1', real_win_match_cnt1, real_win_match_cnt1/len(data_dict_label))
+    print('real_win_match_cnt2', real_win_match_cnt2, real_win_match_cnt2/len(data_dict_label))
+    print('real_win_match_cnt3', real_win_match_cnt3, real_win_match_cnt3/len(data_dict_label))
+
+
+def compare_extract_entity():
+    df1 = pd.read_excel('df_train.xlsx')
+    df2 = pd.read_excel('df_train_doubao.xlsx')
+    # df3 = pd.read_excel(r'D:\BIDI_DOC\比地_文档\export_entity_260414_0.8B_prefix_only_tenderee.xlsx')
+    df3 = pd.read_excel(r'D:\BIDI_DOC\比地_文档\export_entity_260414_0.8B_prefix_only_tenderee_all.xlsx')
+
+
+    df1 = df1[:200]
+
+    data_list1 = df1.astype(object).where(pd.notnull(df1), None).values.tolist()
+    data_list2 = df2.astype(object).where(pd.notnull(df2), None).values.tolist()
+    data_list3 = df3.astype(object).where(pd.notnull(df3), None).values.tolist()
+
+    data_dict1 = {x[2]: x for x in data_list1}
+    data_dict2 = {x[0]: x[2] for x in data_list2}
+    data_dict3 = {x[0]: psv_to_dict_prefix(x[1]) for x in data_list3}
+
+    match_cnt_2 = 0
+    match_cnt_3 = 0
+    all_cnt = 0
+    for docid, line in data_dict1.items():
+        content = line[5] + line[1] + line[8]
+        label = line[4]
+        entity = line[1]
+
+        if label == '其他角色':
+            continue
+
+        if line[4] != '招标人':
+            tenderee1 = '-'
+            continue
+        else:
+            tenderee1 = line[1]
+
+        result_dict2 = data_dict2.get(docid)
+        result_dict2 = repair_json(result_dict2)
+        result_dict2 = json_repair.loads(result_dict2)
+        tenderee2 = result_dict2.get('招标信息', {}).get('招标人名称')
+        if not tenderee2:
+            tenderee2 = '-'
+        if tenderee1 == tenderee2:
+            match_cnt_2 += 1
+        else:
+            print('not match2', tenderee1, tenderee2)
+            print('content', content)
+            print('label', label, entity)
+
+        result_dict3 = data_dict3.get(docid)
+        tenderee3 = result_dict3.get('招标信息', {}).get('招标人名称')
+        if not tenderee3:
+            tenderee3 = '-'
+
+        if tenderee1 == tenderee3:
+            match_cnt_3 += 1
+        else:
+            print('not match3', tenderee1, tenderee3)
+
+        all_cnt += 1
+
+    print('match_cnt_2', match_cnt_2, all_cnt, match_cnt_2 / all_cnt)
+    print('match_cnt_3', match_cnt_3, all_cnt, match_cnt_3 / all_cnt)
+
+
+if __name__ == '__main__':
+    # compare_extract_csv()
+
+    # compare_extract_csv_prefix()
+
+    # compare_extract_entity()
+
+    compare_extract_csv_prefix2()
+

+ 216 - 0
qwen_lora/compare_utils.py

@@ -0,0 +1,216 @@
+import json
+import re
+from decimal import Decimal
+from fuzzywuzzy import fuzz
+
+
+def getDigitsDic(unit):
+    '''
+    @summary:拿到中文对应的数字
+    '''
+    DigitsDic = {"零":0, "壹":1, "贰":2, "叁":3, "肆":4, "伍":5, "陆":6, "柒":7, "捌":8, "玖":9,
+                 "〇":0, "一":1, "二":2, "三":3, "四":4, "五":5, "六":6, "七":7, "八":8, "九":9}
+    return DigitsDic.get(unit)
+
+
+
+def getMultipleFactor(unit):
+    '''
+    @summary:拿到单位对应的值
+    '''
+    MultipleFactor = {"兆":Decimal(1000000000000),"亿":Decimal(100000000),"万":Decimal(10000),"仟":Decimal(1000),"千":Decimal(1000),"佰":Decimal(100),"百":Decimal(100),"拾":Decimal(10),"十":Decimal(10),"元":Decimal(1),"圆":Decimal(1),"角":round(Decimal(0.1),1),"分":round(Decimal(0.01),2)}
+    return MultipleFactor.get(unit)
+
+
+def getUnifyMoney(money):
+    '''
+    @summary:将中文金额字符串转换为数字金额
+    @param:
+        money:中文金额字符串
+    @return: decimal,数据金额
+    '''
+    if money in [None, '', '-']:
+        return Decimal(0)
+    money = str(money)
+
+    MAX_MONEY = 1000000000000
+    MAX_NUM = 12
+    #去掉逗号
+    money = re.sub("[,,]","",money)
+    money = re.sub("[^0-9.零壹贰叁肆伍陆柒捌玖拾佰仟萬億圆十百千万亿元角分]","",money)
+    result = Decimal(0)
+    chnDigits = ["零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"]
+    # chnFactorUnits = ["兆", "亿", "万", "仟", "佰", "拾","圆","元","角","分"]
+    chnFactorUnits = ["兆", "亿", "万", "仟", '千', "佰", '百', "拾", '十',"圆", "元", "角", "分"]  # 20240611 修复大写提取错误 '陆拾陆亿伍千柒佰零叁万肆千叁佰陆拾伍元' Decimal('11607430365')
+
+    LowMoneypattern = re.compile("^[\d,]+(\.\d+)?$")
+    BigMoneypattern = re.compile("^零?(?P<BigMoney>[%s])$"%("".join(chnDigits)))
+    try:
+        if re.search(LowMoneypattern,money) is not None:
+            return Decimal(money)
+        elif re.search(BigMoneypattern,money) is not None:
+            return getDigitsDic(re.search(BigMoneypattern,money).group("BigMoney"))
+        for factorUnit in chnFactorUnits:
+            if re.search(re.compile(".*%s.*"%(factorUnit)),money) is not None:
+                subMoneys = re.split(re.compile("%s(?!.*%s.*)"%(factorUnit,factorUnit)),money)
+                if re.search(re.compile("^(\d+)(\.\d+)?$"),subMoneys[0]) is not None:
+                    if MAX_MONEY/getMultipleFactor(factorUnit)<Decimal(subMoneys[0]):
+                        return Decimal(0)
+                    result += Decimal(subMoneys[0])*(getMultipleFactor(factorUnit))
+                elif len(subMoneys[0])==1:
+                    if re.search(re.compile("^[%s]$"%("".join(chnDigits))),subMoneys[0]) is not None:
+                        result += Decimal(getDigitsDic(subMoneys[0]))*(getMultipleFactor(factorUnit))
+                # subMoneys[0]中无金额单位,不可再拆分
+                elif subMoneys[0]=="":
+                    result += 0
+                elif re.search(re.compile("[%s]"%("".join(chnFactorUnits))),subMoneys[0]) is None:
+                    # print(subMoneys)
+                    # subMoneys[0] = subMoneys[0][0]
+                    result += Decimal(getUnifyMoney(subMoneys[0])) * (getMultipleFactor(factorUnit))
+                else:
+                    result += Decimal(getUnifyMoney(subMoneys[0]))*(getMultipleFactor(factorUnit))
+                if len(subMoneys)>1:
+                    if re.search(re.compile("^(\d+(,)?)+(\.\d+)?[百千万亿]?\s?(元)?$"),subMoneys[1]) is not None:
+                        result += Decimal(subMoneys[1])
+                    elif len(subMoneys[1])==1:
+                        if re.search(re.compile("^[%s]$"%("".join(chnDigits))),subMoneys[1]) is not None:
+                            result += Decimal(getDigitsDic(subMoneys[1]))
+                    else:
+                        result += Decimal(getUnifyMoney(subMoneys[1]))
+                break
+    except Exception as e:
+        # traceback.print_exc()
+        return Decimal(0)
+    return result
+
+
+def text_sim(s1, s2):
+    s1 = str(s1 or "").strip()
+    s2 = str(s2 or "").strip()
+    if not s1 and not s2:
+        return 1.0
+    if not s1 or not s2:
+        return 0.0
+    return fuzz.token_sort_ratio(s1, s2) / 100
+
+
+def num_sim(n1, n2):
+    try:
+        a = float(n1)
+        b = float(n2)
+    except:
+        return 0.0
+    diff = abs(a - b)
+    return 1.0 - diff / max(a, b, 0.01)
+
+
+def product_similarity(p1, p2):
+    score = 0.0
+
+    # score += text_sim(p1.get("产品名称"), p2.get("产品名称")) * 0.4
+    # score += text_sim(p1.get("规格型号"), p2.get("规格型号")) * 0.3
+    # score += text_sim(p1.get("品牌"), p2.get("品牌")) * 0.1
+    # score += num_sim(p1.get("单价"), p2.get("单价")) * 0.08
+    # score += num_sim(p1.get("数量"), p2.get("数量")) * 0.06
+    # score += num_sim(p1.get("总价"), p2.get("总价")) * 0.06
+
+    score += text_sim(p1.get("产品名称"), p2.get("产品名称")) * 0.125
+    score += text_sim(p1.get("规格型号"), p2.get("规格型号")) * 0.125
+    score += text_sim(p1.get("品牌"), p2.get("品牌")) * 0.125
+    score += num_sim(p1.get("单价"), p2.get("单价")) * 0.125
+    score += num_sim(p1.get("数量"), p2.get("数量")) * 0.125
+    score += num_sim(p1.get("总价"), p2.get("总价")) * 0.125
+    score += text_sim(p1.get("品目编号"), p2.get("品目编号")) * 0.125
+    score += text_sim(p1.get("品目名称"), p2.get("品目名称")) * 0.125
+
+    return score
+
+
+def calculate_matching_ratio(list_a, list_b, threshold=0.6):
+    if list_a is None or list_b is None:
+        return 0
+
+    used_b = [False] * len(list_b)
+    match_count = 0
+
+    for a in list_a:
+        best_score = 0
+        best_idx = -1
+
+        for i, b in enumerate(list_b):
+            if used_b[i]:
+                continue
+            score = product_similarity(a, b)
+            if score > best_score:
+                best_score = score
+                best_idx = i
+
+        if best_score >= threshold:
+            match_count += 1
+            if best_idx != -1:
+                used_b[best_idx] = True
+
+    total = max(len(list_a), len(list_b))
+    return match_count / total if total != 0 else 1.0
+
+
+def calculate_complete_match_ratio(list1, list2):
+    if list1 is None or list2 is None:
+        return 0
+
+    example_d = {"产品名称": "树脂等物资", "单价": "未公开", "数量": "未公开", "数量单位": "未公开", "总价": "未公开",
+                 "品牌": "未公开", "规格型号": "未公开", "品目编号": "未公开", "品目名称": "未公开"}
+    cols = list(example_d.keys())
+
+    str_list1 = []
+    for d in list1:
+        str1 = '@'.join([str(d.get(x, '')) for x in cols])
+        str_list1.append(str1)
+    str_list2 = []
+    for d in list2:
+        str2 = '@'.join([str(d.get(x, '')) for x in cols])
+        str_list2.append(str2)
+
+    match_cnt = 0
+    for str1 in str_list1:
+        if str1 in str_list2:
+            match_cnt += 1
+    all_cnt = len(list(set(str_list1) | set(str_list2)))
+    ratio = round(match_cnt / all_cnt, 2)
+    return ratio
+
+
+def calculate_cnt_ratio(list1, list2):
+    if list1 is None:
+        list1 = []
+    if list2 is None:
+        list2 = []
+
+    if len(list1) == len(list2):
+        return 1
+    else:
+        return 0
+
+
+def compare_products(product_list1, product_list2):
+    product_list1 = json.dumps(product_list1, ensure_ascii=False)
+    product_list2 = json.dumps(product_list2, ensure_ascii=False)
+    product_list1 = re.sub('未公开', '', product_list1)
+    product_list2 = re.sub('未公开', '', product_list2)
+    product_list1 = json.loads(product_list1)
+    product_list2 = json.loads(product_list2)
+
+    money_cols = ['单价', '总价']
+    if product_list1:
+        for d in product_list1:
+            for col in money_cols:
+                d[col] = getUnifyMoney(d.get(col))
+    if product_list2:
+        for d in product_list2:
+            for col in money_cols:
+                d[col] = getUnifyMoney(d.get(col))
+
+    weight_score = calculate_matching_ratio(product_list1, product_list2)
+    complete_score = calculate_complete_match_ratio(product_list1, product_list2)
+    cnt_score = calculate_cnt_ratio(product_list1, product_list2)
+    return weight_score, complete_score, cnt_score

BIN
qwen_lora/data_files/260403_ai_人工标注_招标人表达_3_再人工.xlsx


BIN
qwen_lora/data_files/260403_ai_人工标注_招标人表达_3_再人工_html.xlsx


BIN
qwen_lora/data_files/260403_ai_人工标注_招标人表达_3_再人工_json.xlsx


BIN
qwen_lora/data_files/df_train.xlsx


BIN
qwen_lora/data_files/df_train_doubao.xlsx


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
qwen_lora/data_files/document_tmp_has_ai_no_attachment_260327_limit.csv


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 2115 - 0
qwen_lora/data_files/export_ai_260327_2.csv


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1187 - 0
qwen_lora/data_files/export_ai_260417_saimofei_html.csv


BIN
qwen_lora/data_files/export_ai_260506_doubao.xlsx


BIN
qwen_lora/data_files/export_entity_260414_0.8B_prefix_only_tenderee_all.xlsx


BIN
qwen_lora/data_files/招标人_中标人_标注_260421 (1).xlsx


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 18 - 0
qwen_lora/data_files/招标人_中标人_标注_260421_html.csv


+ 1050 - 0
qwen_lora/data_files/招标人_中标人_标注_260421_tenderee_win_2.csv

@@ -0,0 +1,1050 @@
+docid,tenderee,win_tenderer
+762322584,云南保山电力股份有限公司,云南通变电器有限公司
+762704928,大连市中山区市政公用事业服务中心,大连花卉苗木绿化工程有限公司
+762184003,颍上县江口镇人民政府,安徽晟晨建设有限公司
+762683189,罗甸县水务工程建设站,中筑工程设计有限公司
+762399083,国网河南省电力公司郑州供电公司,
+762614809,攀钢集团物资贸易有限公司,四川鸿舰重型机械制造有限责任公司
+757766055,台州东投交旅文化发展有限公司,
+762312596,南通四建集团有限公司,南通天衡建设工程有限公司
+762578028,赣州顺浩投资有限公司,
+762157005,榆林市榆阳区林业投资有限公司,
+762456508,雄县公安局,中电信数智科技有限公司河北分公司
+762371504,寿县人民医院,安徽中隐建设有限公司
+761519733,安阳县农业农村局,安阳标普农业科技有限公司
+761491395,兰州市中医医院(兰州市第四人民医院),
+762712013,阳江市江城区自然资源局,阳江市江城区海迅汇电脑店
+761172111,中国铁路上海局集团有限公司,
+762651099,中国人寿保险(集团)公司,睿泉(北京)咨询有限公司
+762685060,四川发展天瑞矿业有限公司,
+762675029,泉州市公路事业发展中心直属分中心,内蒙古众成建设有限公司
+762710175,浙江歌瑞新材料有限公司,浙江双屿智能科技有限公司
+762670032,中石化湖南石油化工有限公司,
+762705529,六盘水市水城区宏盛建筑工程有限责任公司,贵州恒顺飞翔劳务有限公司
+762662523,重庆水利电力职业技术学院,重庆皓辰建设工程咨询有限公司
+762451674,临朐沂山实业有限公司,
+762716035,佳木斯市园林事业发展中心,中泰正信工程管理咨询有限公司
+761661422,台州市生态环境局临海分局,宁波理工环境能源科技股份有限公司
+762662010,浙江新安化工集团股份有限公司,
+755756508,中国航发哈尔滨东安发动机有限公司,
+762709539,中国邮政集团有限公司重庆市分公司,廊坊市燕京安全印务有限公司
+762673001,中复神鹰碳纤维股份有限公司,
+762659135,漳浦县交通运输局,
+762675530,佛山市高明区更合镇中心小学,
+762678025,内蒙古伊泰呼准铁路有限公司,准格尔旗铁信商贸有限责任公司
+762667505,焦作市第十五中学,
+762710177,中共孝感市孝南区委办公室,孝感市云印宝快印中心
+758158378,衢南文化旅游中心,
+762692512,中国化学工程第三建设有限公司,山东省显通安装有限公司
+762303093,赣州市南康区第三中学,
+762701445,广东海洋大学,广东新可宇建设集团有限公司
+762577120,杭州余杭城体建设发展有限公司,浙江省通信产业服务有限公司
+762272529,阳新县第二实验小学,阳新县兴国镇臻恒电脑商行
+762260338,,
+762664064,中国平煤神马控股集团有限公司招标采购中心,平顶山欣毅机械制造有限公司
+762355048,临沂市公安局交通警察支队平邑大队,山东众博智能科技有限公司
+762166031,西安东方航空食品有限公司,
+762169044,泸州市龙驰建筑工程有限公司,
+762210107,成都云图控股股份有限公司,
+758667493,诏安县建设乡万石溪村村民委员会,万石溪村木屋八仙茶互动交流中心
+762174542,阜阳市建投置业有限公司,
+753750691,乐清市虹桥镇南阳村集体经济组织,乐清市方圆建筑安装工程有限公司
+762183509,北京市丰台区人民政府长辛店街道办事处,北京市开元长泰建筑工程有限责任公司
+762675505,喀喇沁左翼蒙古族自治县羊角沟镇产业发展服务中心,辽宁新达诚建设发展有限公司
+762083067,山西安泰集团股份有限公司,
+762483572,赣州市粮食集团有限责任公司,
+762678500,义乌市深能再生资源利用有限公司,
+762698006,长沙市公安局,
+762695347,营口方大医院有限公司,
+762261046,杭州市富阳区第二人民医院,
+762720155,南京启城城市建设发展有限公司,
+761708564,六安市裕安区林业发展中心,
+755270066,苏州市药品检验检测研究中心(苏州市药品不良反应监测中心),
+762645507,重庆庆龙新材料科技有限公司,重庆恩凯勒机电设备有限公司
+762465603,砚山县公安局,中国石油天然气股份有限公司云南文山销售分公司
+762159056,阜阳师范大学,
+762683284,北京中石油彩色印刷有限责任公司,
+762218515,西南政法大学,
+762670515,山东省机场管理集团济南国际机场股份有限公司,
+759122815,石狮市城市物业管理有限公司,泉州市睿驰清洁用品有限公司
+762496032,西宁市第一人民医院,
+762449065,广东金盾服装有限公司,
+762703848,新兴铸管股份有限公司供应链分公司,
+762660669,淄博市自然资源和规划局,
+754629262,大庆油田华谊实业有限公司,大庆市昱瑞食品有限公司
+762681598,贵州乌江水电开发有限责任公司构皮滩发电厂,南京南瑞继保电气有限公司
+762094567,中国电建集团贵州工程有限公司,
+762704699,深圳市政集团有限公司,国任财产保险股份有限公司深圳分公司
+762671992,牟定县城乡供排水有限公司,
+762149065,合肥木槿堂中医诊所,合肥市包河区卫生健康委员会
+762542570,宜丰县石花尖垦殖场,宜丰县称心文化店
+762719014,江西产控招商集团有限公司,
+762668014,贵州枫阳液压有限责任公司,
+762660185,浙江英诺珐医药有限公司,北京美兴科技有限公司
+761603446,阿鲁科尔,
+761046729,湘潭市中级人民法院,湖南正融价格评估有限公司
+619610262,中山市坦洲镇十四村股份合作经济联合社,广东文恒建设工程有限公司
+753027950,新乡市审计局,永道工程咨询(江苏)有限公司
+762715508,成都霍森斯幼儿园,成都市宇菲装修工程有限责任公司
+762665002,邯郸市冀南建设投资集团有限公司,
+762615032,万华化学(宁波)有限公司,宁波防雷安全检测有限公司
+762580062,德江县民族中学,德江县顺欣家具厂
+762658109,宜昌产投建设投资有限公司,中铁建设集团机电安装有限公司
+755217246,天门市公共资源交易中心,
+762653518,江西省肿瘤医院(江西省第二人民医院、江西省癌症中心),
+762141540,南平市延平区第二实验幼儿园,南平市银河库区建设工程有限公司
+762675647,上海振华重工(集团)股份有限公司,上海麦杰科技股份有限公司
+762577621,上海市浦东新区合庆镇人民政府,上海镜视环保科技有限公司
+760917812,温县住房和城乡建设局,三赢建设集团有限公司
+762143593,瑞鲸(安徽)供应链科技有限公司,
+761724037,河南省济源第一中学,济源汇通环卫服务有限公司
+762639508,长岭县巨宝山镇人民政府,
+761434280,济源产城融合示范区教育体育局,河北康奥达体育用品有限公司
+762700010,成都市公共交通集团有限公司,中国银行股份有限公司成都金牛支行
+754223586,重庆市农业投资集团有限公司,
+759611990,江苏海洋大学,
+762704528,石家庄铁路运输学校,
+762692527,青神县青竹街道黑龙社区居民委员会,
+762137542,成都生物城股权投资基金管理有限公司,
+762645500,宝钢(武汉)材料科技有限公司,景林包装机械(常州)有限公司
+762387030,交通银行股份有限公司贵州省分行,
+762663517,云南华联锌铟股份有限公司,中国有色金属工业昆明勘察设计研究院有限公司
+762654057,中国石油天然气股份有限公司抚顺石化分公司,青岛维康中油检测有限公司
+762365602,蚌埠融兴建设发展有限责任公司,中建四局第六建设有限公司
+762163058,成都市畜禽遗传资源保护中心,四川天信四合科技有限公司
+762688031,内蒙古吉源热电有限责任公司,
+762369088,四川润昌共兴实业发展有限公司,
+762660180,韶州人民医院,
+757449884,,
+762679138,中国光大银行股份有限公司西宁分行,青海文礼人力资源服务有限公司
+762323129,莱西市农业农村局,
+758178631,温岭市人民检察院,
+762711001,海安市人民医院,
+762718012,揭阳市榕城区进贤门街道办事处,揭阳市弘泰物业管理有限公司
+762501111,中共深圳市宝安区委社会工作部,深圳市宝安区慧家社会事务服务中心
+762428075,山东第二医科大学,潍坊昌大建设集团有限公司
+762665010,东方电气集团东方电机有限公司,
+762692702,陕西省第一届冬季运动会榆林市筹委会,陕西特普康医疗科技有限公司
+762664192,湘乡市交通运输局,张家界市公路工程监理咨询有限责任公司
+762400237,揭阳市榕城区文化旅游体育局,广东和睦建设工程有限公司
+762722035,安徽省司法厅,
+761472492,海南师范大学,海南万峰装饰工程有限公司
+762709526,黑龙江农业职业技术学院,
+762712509,随州市中医医院,武汉康宸瑞达商贸有限公司
+762682251,海南省体育赛事中心,海南省轮滑协会
+754468836,昆明自动化成套集团股份有限公司,
+762372160,青岛市住房和城乡建设局,
+762715004,绵阳市富乐山风景区管理中心,龙泉驿区龙泉街办华美花卉经营部
+762672926,山东医药大学,山东中册智慧科技集团有限公司
+762721510,四川洲际恒远建设工程有限公司,四川交承建筑安装工程有限公司
+762662025,国投哈密实业有限责任公司,陕西英发创联信息技术有限公司
+762160033,中国工程物理研究院应用电子学研究所,上海船用柴油机研究所(中国船舶集团有限公司第七一一研究所)
+761184532,江苏省市场监督管理局,
+762720534,河南交通投资集团有限公司安阳分公司,河南交投文化传媒有限公司
+762694531,贺州市八步区交通运输局,广西交科集团有限公司
+762440573,晋中市农业农村局,
+762061933,辛集市土地储备中心,
+760702208,嘉兴科技城建设投资有限公司,
+762659205,中国原子能科学研究院,大连兴航机械技术有限公司
+762693026,昆明市城市管理局,森特土壤修复研究院(深圳)有限公司
+762188076,武汉东湖新技术开发区关东街道办事处,武汉东湖新技术开发区广圣办公家具经营部
+762654518,中国航发航空科技股份有限公司,
+762671029,三一集团有限公司,
+762134033,海南天然橡胶产业集团股份有限公司,
+756260645,紫金山实验室,
+762715018,石家庄博瑞生物科技有限公司,
+762697022,贵州电网有限责任公司贵阳供电局,
+762107586,哈尔滨电气物资有限公司,
+751882974,重庆市铜梁区市政设施管理所,四川宽扬建筑工程有限公司
+762405660,晋州市农业农村局,晋州市德农种植专业合作社
+762723529,上海市长宁区公共卫生中心,
+762702033,北京航天益森风洞工程技术有限公司,
+762577165,西安经建科技工程有限责任公司,庆阳祥威环保科技发展有限公司
+762668648,重庆三峰卡万塔环境产业有限公司,上海密尔克卫化工物流有限公司
+762243002,广州白云空港设备技术发展有限公司,
+762674071,景德镇市国营大岭垦殖场,景德镇翔铃汽车销售服务有限公司
+762465079,大通回族土族自治县东峡林场,
+762682004,中国石化长城能源化工(宁夏)有限公司,南阳市恒汇办公设备有限公司
+762510003,临海市上盘镇人民政府,台州市邦达建设有限公司
+762723518,广西六通供应链管理有限公司,
+762674501,辽宁港口股份有限公司,
+762670010,天津外国语大学附属外国语学校,
+762690500,海南省海洋和渔业监察总队,海口德丰利船舶用品有限公司
+761392362,深圳理工大学总医院,
+761647370,常州迅安科技股份有限公司,
+762506061,南京鼓楼医院,
+762108088,闽清县农业农村局,闽清县梅城镇志豪汽车修理厂
+762660033,内蒙古蒙牛乳业(集团)股份有限公司,
+758916392,深圳市龙岗区妇幼保健院(深圳市龙岗区妇幼保健计划生育服务中心),
+762727007,晋能控股山西煤业股份有限公司塔山铁路分公司,
+762681535,南宁建宁智慧生活服务有限公司,
+760946046,云梦县熊家山公墓服务中心,云梦县浩顺设备租赁门市部
+762151582,重庆长寿中法水务有限公司,
+762711515,广州市越堡水泥有限公司,
+762661613,德钦县城地质灾害防治和搬迁避让工作指挥部,云南隆强建设工程监理有限公司
+762080061,山西五建集团有限公司,
+761601363,庐江县第三人民医院,庐江益得商贸有限公司
+762628014,深圳能源环保股份有限公司,
+762310629,深圳市科技创新局,
+762208967,岳阳县畜牧水产发展服务中心,岳阳县长信农业开发有限公司
+762714017,金堂县第一人民医院,浙江网新健康科技有限公司
+762672225,漳州台商投资区城市更新建设发展有限公司,漳州城投设计咨询集团有限公司
+760974163,昆山市农业农村局(昆山市乡村振兴局),台雅兽药(昆山)有限公司
+762723503,珠海市生态环境局香洲分局,广东中检源检测有限公司
+762669358,太仓中集冷藏物流装备有限公司,
+762660198,铜陵港务有限责任公司,安徽恩测检测技术有限公司
+750163515,武汉经济技术开发区(汉南区)教育局,
+762677525,丰城市市政园林服务中心,江西省俊祥建筑工程有限公司
+762670514,华生集团,
+762689531,北京航天新立科技有限公司,
+755253685,商洛职业技术学院,
+761172411,内江市东兴区经济信息化和科学技术局,四川并济科技有限公司
+761647960,荣成市体育发展中心,威海超越体育文化传播有限公司
+761513415,金发科技股份有限公司,
+760903530,天津市水文水资源管理中心,
+762712492,内蒙古京隆发电有限责任公司,
+762661030,中国核工业建设股份有限公司,闻名钢结构(上海)有限公司
+751110907,中旅投资(四川)有限公司,
+762358696,新疆应用职业技术学院,幼乐美(北京)教育科技有限公司
+762675004,新乐市中医医院,河北诺德医药物流有限公司
+762675027,铜陵有色金属集团股份有限公司,
+762686729,风神轮胎股份有限公司,
+762715521,,
+762671216,沈阳化工大学,辽宁省建筑设计研究院有限责任公司
+762675517,河北润安贸易有限公司,
+762686353,铜陵职业技术学院,
+761083825,云南云天化工业装备技术有限公司,
+762675526,合肥市经贸旅游学校,
+755263145,阜宁县三灶镇人民政府,淮安百洋建设工程有限公司
+762648208,中铁十局集团第七工程有限公司,
+762677641,青海西矿稀贵金属有限公司,
+761512332,陕西宏远航空锻造有限责任公司,
+762599029,成都建工第四建筑工程有限公司,浙江久石工研建材科技有限公司
+762664014,山东省路桥集团有限公司,
+762619611,湖北水利水电职业技术学院,宏鸣建设湖北有限公司
+762369557,吴忠市清宁福居投资建设有限公司,吴忠市顺通建筑工程有限公司
+762670653,邯郸市交通运输局干线公路建设管理中心,瑞和安惠项目管理集团有限公司
+762696502,湖南省信宇置业有限公司,江苏润来建设集团有限公司
+762664034,石家庄市建筑工程有限公司,
+762593039,福建省龙岩市永定区大溪中心小学,福建省鑫强盛建筑工程有限公司
+762335018,大连金普新区档案馆,
+752844180,湖北泰盛化工有限公司,
+762654582,湘南片区供应中心,
+762690710,广元市数字经济集团有限公司,成都创信华通信息技术有限公司
+762650097,湖南省先导现代园林绿化有限公司,湖南国际华远装饰有限公司
+762384048,广州市越德企业管理咨询有限公司,
+762230509,新疆生产建设兵团第七师一三〇团连队,胡杨河市百惠美居商贸有限公司
+762579519,兰州新区自然资源和规划局,
+762352079,成都轨道城市投资集团有限公司,成都凌视文化传播有限责任公司
+762110533,光环江东环保能源(马鞍山)有限公司,
+762705111,北京宇航高科新材料有限公司天津分公司,
+762703521,天津滨海新区环塘污水处理有限公司,天津国利技术有限公司
+755056057,许昌学院附属中学,许昌市新献商贸有限公司
+762706009,黑龙江路悦建设工程有限公司,
+762164617,太原重工股份有限公司,
+762702007,中铁十一局集团电务工程有限公司,
+761671319,雷波县农业技术推广中心,四川宏本建筑工程有限公司
+762663522,山东海化集团有限公司,济南森峰激光科技股份有限公司
+762690097,华侨城中部集团有限公司,武汉注融文化传媒有限公司
+762598603,四川纹江致远建筑开发工程有限公司,华农财产保险股份有限公司四川省分公司
+762386071,攀枝花市中西医结合医院,
+762234524,西安西部新锆科技股份有限公司,
+762644029,招金矿业股份有限公司,招远市厚海矿山设备有限公司
+761729227,淮南市九龙岗镇人民政府,
+762464512,四川艺术职业学院,
+762025058,武威市机关事务管理局,武威嘉阳汽车销售服务有限公司
+762714516,韶关高新区财政局,驿涛工程集团有限公司
+762496053,兴文县兴农发展投资集团有限责任公司,四川久宏建设工程有限责任公司
+762261098,上海市闵行区莘庄镇人民政府,上海安康旅行社有限公司
+762312051,际头村良马线乡村旅游驿站,
+762680501,丰县道路管理所,江苏东交智控科技集团股份有限公司
+762662609,长春市新净发城中村改造房地产开发有限公司,吉林省神力电力工程有限责任公司
+762722533,中国共产党田东县委员会统一战线工作部,广西博臣建筑工程有限公司
+762656008,邯郸市邯钢附属企业公司,
+762709534,浙江嘉维旅游有限公司,浙江华喆建设有限公司
+762725013,昆明长水国际机场有限责任公司,上海华程西南国际旅行社有限公司
+762232102,深圳市龙安物业管理有限公司,
+762515560,乌鲁木齐市第一人民医院(乌鲁木齐儿童医院),
+762684507,中国石油化工股份有限公司荆门分公司,
+762709507,哈尔滨市口腔医院,哈尔滨市香坊区通普办公用品商店(个体工商户)
+762687159,蒸湘区农业农村局,湖南启融工程建设有限公司
+762686014,中航成飞民用飞机有限责任公司,
+762590565,通号(郑州)电气化局集团有限公司第四分公司,河南芒午商贸有限公司
+762685020,中卫市司法局,宁夏君元律师事务所
+761109631,赤城县林业和草原局,
+762670522,国电投(山东)新能源开发有限公司,
+761297980,阳江市阳东区妇幼保健院,广东众诺价格鉴定评估有限公司
+762655527,中建桥梁有限公司浙江分公司,河北邦德威电力器材股份有限公司
+762646524,山东省高速养护集团有限公司四公司,山东恒烨路桥工程有限公司
+762687464,国家税务总局丹阳市税务局,
+762686209,,上海准航电子有限公司
+762705060,固安产业新城发展集团有限公司,固安九通基业公用事业有限公司
+762681569,黑龙江省八达路桥建设有限公司黑河分公司,黑龙江省安润吉运输有限公司
+762437913,嘉兴市嘉兴鑫舜隆农业开发有限公司,嘉兴鑫舜隆农业开发有限公司
+762675511,徐州徐工液压件有限公司,
+762710521,华润水泥(安顺)有限公司,
+762710512,四川公路桥梁建设集团有限公司公路隧道分公司,
+753592619,象州县中学,
+762647197,天水输油气分公司,中起建工集团有限公司
+762680562,罗甸县水务工程建设站,
+762289488,国家税务总局天津市河西区税务局,天津神州浩天科技有限公司
+762654164,安徽建工集团新时代物业管理有限公司,临泉县吉程建筑工程有限公司
+761312736,阿克苏市水资源总站,
+762191617,黑龙江农业经济职业学院,牡丹江恒岳科技有限公司
+762679222,凌云华工智能系统(武汉)有限公司,华工法利莱切焊系统工程有限公司
+753644829,海南鲁骐产业投资有限公司,
+762705027,东山县杏陈镇大产村民委员会,福州闽川工程咨询有限公司
+762646359,上海航天汽车机电股份有限公司,
+762700554,一汽铸造有限公司,山东格瑞德集团有限公司
+762658523,德州市实验中学,德州市德城区军一电气焊不锈钢维修部
+762455558,深能环发城市运营服务(肇庆)有限公司,封开县江口镇骏景商行
+762182777,温宿县交通运输局,
+761523936,龙建路桥股份有限公司同江分公司,
+751430790,重庆市铜梁区平滩镇人民政府,重庆市东山建筑安装工程有限公司
+762670071,湖北省烟草公司宜昌市公司,宜昌洺舟人力资源服务有限责任公司
+762594552,大宁县水利发展中心,弘飞建工集团有限公司
+762722028,盘锦港集团有限公司集装箱分公司,
+762372006,厦门市海沧区农业农村和水利局,厦门海投文旅产业发展有限公司
+762207111,重庆双五汽车零部件有限公司,
+762686019,天津市自来水集团有限公司,
+762687006,合肥北城安丰运营管理有限公司,安徽海富建设有限公司
+762644504,上海振华重工(集团)股份有限公司长兴分公司,
+762095525,上海华众凌羽新材料科技有限公司,
+762370100,交口县城乡建设和交通运输局,
+762663000,安阳市司法局,安阳市尚百帮社会工作服务中心
+761232015,开平市科工商务局(开平市口岸局),开平市汇港贸易有限公司
+751073454,宁波中意海晟城市开发有限公司,
+762669535,唐山市公安局交通管理支队,
+762662035,上海罗星市政道路管理有限公司,上海萱赢实业有限公司
+760263720,厦门农产品有限公司,厦门为峰机电科技有限公司
+762720512,深圳广播电影电视集团,深圳市德居投资顾问有限公司
+762666512,鲁西集团有限公司,
+756208699,亚泰集团,
+752728230,内蒙古超高压供电公司,项城市永通电力工程有限公司
+758029338,资阳市公用事业服务中心,成都市温江区繁盛园林苗圃场
+762399112,蓝山县公安局交通管理大队,湖南捷拓科技有限公司
+752885723,高铁新城新综合客运服务中心,
+762390465,辽宁省纪委监委综合保障中心,沈阳明汇丰食品配送有限公司
+762639565,泰州职业技术学院,泰州恒盛智能化工程有限公司
+762303531,深州市财政局,双辉劲达建设工程集团有限公司
+762705136,苏州交投建设管理有限公司,江苏省太湖水利规划设计研究院有限公司
+762704798,河南钢铁,
+762672003,兖矿能源集团股份有限公司南屯煤矿,邹城市航泰建设工程有限公司
+762660005,大秦铁路股份有限公司侯马电务段,林州市中联铸锻有限公司
+762347582,乌审旗教育体育局,
+761471171,石家庄市桥西区人民政府办公室,
+761677991,藁城区人民政府,
+762713020,红狮集团,
+762662520,黑龙江东科建设集团有限公司,
+762094568,中交建筑集团第五工程有限公司,
+757013581,将乐县水利局,
+762249107,宁城县忙农镇人民政府,宁城县北联电脑商行
+762677051,贵州能源集团电力投资有限公司,贵州金诚环保科技有限公司
+762663031,中国移动通信集团北京有限公司,北京天融信网络安全技术有限公司
+762717017,中粮米业(大连)有限公司,
+759299207,固原市原州区农业技术推广服务中心,
+762652506,中铁六局集团天津铁路建设有限公司,
+762351093,南京智能制造产业园建设发展有限公司,南京江电建设工程有限公司
+762675489,张家港市第一中学,江苏特零网络科技有限公司
+752605642,四川省巴中生态环境监测中心站,
+762153112,中国电信股份有限公司周口分公司,
+762680248,中牟县中医院(中牟县中医院总医院),河南君威保安服务有限公司
+762676287,成都市金牛区人民法院,
+762647004,中石油云南石化有限公司,
+762483601,湖州锦实股权投资有限公司,
+757722816,昌乐众兴水务有限公司,
+762443513,上海市浦东新区人民医院,上海群华办公用品有限公司
+754444407,深圳市儿童医院,
+762661522,固阳义正诚碳素有限公司,
+762671027,自然资源部第三海洋研究所,
+762709533,同江市城市管理综合行政执法大队,
+762694527,晋城市住房事业服务中心,中国建设银行股份有限公司晋城分行
+762375883,陕西延长石油(集团)有限责任公司延长气田采气三厂,
+762677514,中国石油天然气股份有限公司独山子石化分公司,
+762678533,上海宝冶集团中冶路桥建设有限公司,中舰建筑工程(天津)有限公司
+761194022,湖北省交通规划设计院股份有限公司,
+757697633,中交第二航务工程局有限公司,武汉裕森商贸有限公司
+762706012,成都云图控股股份有限公司,
+762720645,杭州地铁运营有限公司,
+762120531,东方电气自动控制工程有限公司,
+762703973,常州新奥燃气发展有限公司,
+760889825,北京市怀柔区教育委员会,北京火炬生地人造草坪有限公司
+762114127,孙吴县大河口林场,中国人寿财产保险股份有限公司黑河市中心支公司
+760712019,深圳市第三人民医院,
+762363141,湖南民族职业学院,岳阳楼区汇联电脑商行
+762703667,河北省公安厅交通科研所,中联建工(北京)建设工程有限公司
+762689697,广西路桥工程集团有限公司,广西业勤项目管理有限公司
+752709627,武汉海王新能源工程技术有限公司,
+762144027,邵阳市公安局,湖南天岭仪器设备有限公司
+762648071,酒钢集团西沟矿业公司,宏大爆破工程集团有限责任公司
+762672090,鞍钢股份有限公司,鞍山科源技术发展有限公司
+762706000,广州工控资产管理有限公司,
+762691514,宁波银行股份有限公司,
+761110104,察雅县水利技术服务队,西藏平衍工程技术咨询有限公司
+762710039,安徽盐业典当有限公司,安徽华安会计师事务所有限公司
+762698017,固原市疾病预防控制中心(固原市艾滋病防治监测中心、固原市地方病防治中心、固原市健康教育所),
+762292600,临海市农业农村局,中国电信股份有限公司台州分公司
+761348394,广州体育学院,
+757846499,山东墨龙石油机械股份有限公司,
+762719015,金隅智信(河北雄安)供应链有限责任公司,天津金石智联科技有限公司
+762299506,卫辉市农业农村局(卫辉市畜牧局),
+762383500,烟台市自然资源和规划局,北京山维科技股份有限公司
+762674757,澄迈澄发公共服务项目管理有限公司,
+762715520,贵州省黔晟国有资产经营有限责任公司,
+762682293,大宁县水利局,岭盛建设集团有限公司
+762700500,铁法煤业(集团)有限责任公司,
+761753678,中国共产党银川市纪律检查委员会,宁夏博晨电子科技有限公司
+762661674,荆门市天宇市政建设有限公司,荆门铭宝建筑劳务有限公司
+762576000,珠海粤水电能源有限公司,广东腾晖电力工程有限公司
+761779742,东山县农业农村局,
+762171085,代县财政局,
+762605020,中车山东风电有限公司,
+760930825,云南旅游职业学院,
+762684950,宁海县国兴能源发展有限公司,
+762691517,中山市公安局翠亨新区分局,
+762662016,际华三五一三实业有限公司,
+762699005,中煤集团山西华昱能源有限公司,
+762691065,中煤集团山西有限公司,山西中圆建筑工程有限公司
+750967065,新乡市自然资源和规划局,
+755795858,吉林省邮政管理局,吉林省为家装饰设计有限公司
+762670157,中石化广州工程有限公司,江苏滔海机械制造有限公司
+762707035,广州白云国际机场地勤服务有限公司,
+762133033,遂昌县建设投资发展有限公司,浙江三琟项目管理有限公司
+761199549,灵武市农业农村局,宁夏海峡文化传媒有限公司
+762207155,东莞市公安局松山湖分局,东莞市常平和盛文具店
+762686509,前郭尔罗斯蒙古族自治县查干湖镇人民政府,
+756371192,叙永县第四中学,
+762140475,福建合盈机械有限公司,福州中亚环保科技有限公司
+762255094,RT地产(江苏)有限责任公司,
+762691720,光大城洁环保能源(张家口)有限公司,山东融盛建设有限公司
+762664171,国家能源能集团,沈阳华电电站工程有限公司
+754656634,亚泰建材双阳公司,
+762686503,丽都饭店有限公司,北京市通盛达市政公用工程有限公司
+762365605,大唐武安发电有限公司,辽宁高辰电力工程技术有限责任公司
+762652696,河北银泓农业发展有限公司,张家口建院工程咨询有限公司
+762362580,宁波枫林绿色能源开发有限公司,
+762658619,中国联合工程有限公司,云南成坦商贸有限公司
+762704094,中汽院(江苏)新能源科技有限公司,浙江名都科技有限公司
+762697536,双辽市柳条乡白牛村经济合作社,
+762687131,长春中医药大学附属第四临床医院,
+762622042,凉州区金沙镇卫生院,甘肃京莱特医疗器械有限公司
+758425204,济源产城融合示范区管理委员会办公室,
+762346096,中色(宁夏)东方集团有限公司物资集采中心分公司,
+762701861,南通市如皋生态环境局,南通大果智能科技有限公司
+762679733,闽侯县上街实验学校,
+762694503,重庆市潼南区政府投资管理中心,重庆力圣建设工程咨询有限公司
+762663681,中煤第三建设(集团)有限责任公司三十六工程处,徐州泓信泰机电有限公司
+762709163,河南医药大学,南京卓梅亚科技有限公司
+761708298,赤峰市松山区人力资源和社会保障局,内蒙古众鼎建设工程有限公司
+762682033,国网山东省电力公司营销服务中心(计量中心),山东航舵信息科技有限公司
+762662531,闻喜县农业农村局,山西好农生农业科技有限公司
+762718535,永康市方岩镇人民政府,中国人民财产保险股份有限公司金华市分公司
+762239518,新疆天富能源股份有限公司,
+761744485,天津市红桥区中医医院,
+762660133,霍邱县蓼城新能源科技有限公司,铁塔能源有限公司安徽分公司
+762361102,宁波市海曙区章水镇人民政府,宁波高专建设监理有限公司
+761544544,上海市松江区城市建设综合管理事务中心,上海瀚世信息技术有限公司
+762699567,江西美福物业服务有限公司,江西省交投养护科技集团有限公司
+762700510,铁法煤业(集团)有限责任公司,
+762647003,孚日集团股份有限公司,
+762722025,兴业银行股份有限公司,
+761155279,中船物业(上海)有限公司,
+762503000,竹山县妇幼保健院(竹山县妇幼保健计划生育服务中心),湖北兴竹建设工程有限公司
+762114013,西部重工公司,
+762099037,泉州市公安局交通管理支队台商投资区大队,泉州市鲤城鑫三高电脑有限公司
+762677522,中煤科工集团武汉设计研究院有限公司,潍坊华肯重工科技有限公司
+762421013,靖江市信华建设有限公司,江苏企瑞工程设计咨询有限公司
+762726009,中煤第三建设(集团)有限责任公司三十工程处,安徽广维精密制造有限公司
+762688515,安徽金岩高岭土新材料股份有限公司,
+762660018,安阳化学工业集团有限责任公司,河北兴东管道有限公司
+762707529,南昌市灌婴小学,
+761380713,江西峰豪混凝土有限公司,
+762226539,北京京粮泰禾房地产有限公司,北京世纪滕迈建筑工程有限公司
+761690037,四川弘石资产管理有限公司,
+762284407,浙江高信技术股份有限公司,中咨公路养护检测技术有限公司
+762702290,河北院石家庄新天智慧能源有限公司,
+761154520,五华县农业农村局,汕尾市润邦检测技术有限公司
+762129035,江西省南昌市青云谱区青云谱镇熊坊村村民委员会,江西新越城市更新有限公司
+762722009,南京三宝科技股份有限公司,
+762679517,山东医学高等专科学校,
+762668190,中煤数字科技(甘肃)有限公司,河南勇创测绘服务有限公司
+757904770,金寨县水利工程建设管理服务中心,安徽海兴生态科技有限公司
+761724920,金乡县卜集镇中心小学,金乡县顺兴贸易有限公司
+762652729,嘉兴金梧桐园林工程有限公司,平湖市新信交通工程有限公司
+761490464,珠海市绿怡物业管理有限公司,珠海市城洁清洁服务有限公司
+762697021,重庆长安工业(集团)有限责任公司,
+762707014,上海振华重工总部,上海晶成建筑安装工程有限公司
+762669556,岱山县长涂镇港南村村民委员会,舟山宇舜建设有限公司
+762131062,定边县农投实业有限公司,榆林华源电力有限责任公司
+762272601,海林市新安朝鲜族镇人民政府,海林市孙艳文教用品有限公司
+762672916,天津港口医院,天津艾迪康医学检验实验室有限公司
+762356517,连州市医疗保障服务中心,
+762586504,西安高铁东城建设发展有限公司,
+762254066,延边大学师范分院附属小学校,延边综艺网络科技有限公司
+762127647,榆林市横山区横山新区管理委员会,信宇腾远规划设计有限公司西安经开分公司
+762674529,华润三九医药股份有限公司,深圳市华浩环保科技有限公司
+762540523,山东滕建建设集团有限公司,
+762707511,榆林市第一医院,北京鸿程瑞源医疗器械有限公司
+762706516,山东第一医科大学(山东省医学科学院),
+762170515,阳光雨露信息技术服务(北京)有限公司哈尔滨服务中心,
+762068031,上海金茂投资管理集团有限公司,
+761501143,广东电网有限责任公司汕尾供电局,广东河海工程咨询有限公司
+762369614,六安市金安区人民法院,
+761738756,临沂市莒南县公路事业发展中心,莒南县刘姐物业服务有限公司
+754929798,水电基础局二公司,
+762660513,中信重工机械股份有限公司,
+759158497,杭州市拱墅区厘望轩小区第一届业主委员会,浙江绿芽房屋科技有限公司
+762719027,赤峰经济开发区发电有限公司,
+762654519,中国电建集团重庆工程有限公司,山东泰开送变电有限公司
+762674015,汕尾市国有东海岸林场,
+762419104,民和回族土族自治县水利设施运行服务中心,青海正和水利水电开发有限公司
+762385517,鄂伦春自治旗大杨树镇人民政府,华辰设计集团有限公司
+762161099,吉安市保育院,江西荣达消防技术服务有限公司
+762681231,中铁特货物流股份有限公司,
+762686703,稻城县林业和草原局,四川锦一建设工程有限公司
+762126118,江汉大学,武汉雅美高印刷有限公司
+762667508,北京恩菲环保股份有限公司,
+755114566,珠海市金湾区连湾小学,海贝研学(广东)国际旅游有限公司
+762368108,深圳市规划和自然资源数据管理中心(深圳市空间地理信息中心),
+762672773,武汉市汉阳区西大街至诚小学,湖北睿志云科技有限责任公司
+762695169,金华市婺城区燕语湖综合开发有限公司,浙江金盾安保集团有限公司
+762327576,威海市环翠区市场监督管理局,山东天弘质量检验中心有限公司
+762676533,吉林省农村产权交易市场有限公司,
+762680592,贵阳宏图科技有限公司,贵州葆怀资产房地产评估事务所(有限合伙)
+762670091,中国华西企业股份有限公司安装工程公司,四川晟通检测有限公司
+751132016,天水市公安局秦州分局,
+762727514,佛山市顺德区李兆基中学,佛山市顺德区金御印刷有限公司
+762392089,成都高新技术产业开发区肖家河街道办事处,
+761694288,贵阳市市场监督管理局(贵阳市知识产权局、贵阳市药品监督管理局),贵州省检测技术研究应用中心
+762672530,东莞科技创新投资集团有限公司,佛山市麟之迪科技有限公司
+762466108,望江县城市管理局(望江县城市管理行政执法局),望江县人防工程有限公司
+762700004,蚌埠市中心血站,上海臻锲贸易有限公司
+762717531,上海东建路支行,上海陆家嘴人才公寓建设开发有限公司
+762702510,南京科瑞达电子装备有限责任公司,南京市橡胶工业研究所
+762688057,苏尼特右旗公安局,中国石油天然气股份有限公司内蒙古锡林郭勒销售分公司
+762702016,海安市白甸镇官垛村股份经济合作社,海安滨恒贸易商行
+762661199,天津商业大学,天津市建筑设计研究院有限公司
+762128535,鸠江区官陡街道社区卫生服务中心,安徽医菲供应链有限公司
+762712522,中兵投资管理有限责任公司,北京广联信达科技有限公司
+761150097,汉寿县农业农村局,汉寿明珠专业种养合作社
+762618029,中山大学,上海天净沙商贸有限公司
+762715514,冀中能源股份有限公司,河北宏矿科技有限公司
+762694521,扎赉特旗农牧和科技局(中共扎赉特旗委员会农村牧区工作领导小组办公室),河南精诚勘测规划设计有限公司
+762575009,广州珠江实业环境保护有限公司,广东华辉建设有限公司
+761667476,福建省石狮供水股份有限公司,
+762723528,中国铁路昆明局集团有限公司,
+759370667,侨福城小区第二届业主委员会,厦门鑫辰昊雅机电设备有限公司
+762460571,高密梦圆家居有限公司,
+762670511,甘肃政法大学,
+762683534,合肥工业大学,合肥市共达汽车服务有限公司
+762714485,呼和浩特市供排水有限责任公司,
+762718023,宁夏枣泉发电有限责任公司,
+762717021,陕西建工新型建设有限公司,陕西绿嘉宏塬建筑工程有限公司
+762344576,铜陵市机关事务管理服务中心,铜陵市天资建设有限公司
+761461459,大连职业技术学院,奕响(北京)科技有限公司
+762663685,内蒙古路桥集团有限责任公司,河南紫光建筑工程有限公司
+762541557,清水县秦亭镇中心卫生院,
+762697031,贝利特化学股份有限公司,
+762642518,北京太阳宫燃气热电有限公司,北京海德斯克科技发展有限公司
+762697005,河北中盐龙祥盐化有限公司,昆山川一五金化工有限公司
+762682209,中国联合网络通信有限公司江西省分公司,深圳市中兴通讯技术服务有限责任公司
+761222698,长葛市城市管理局,长葛市葛天智慧城市运营有限公司
+762673220,云南滇中恒昇投资发展有限公司,中图设计有限公司
+762380000,陕西柴油机重工有限公司西安电站工程分公司,
+762644017,中天合创能源有限责任公司,南京日创自动化仪表工程有限公司
+762142109,大连理工大学,海创(大连)科技交流中心有限公司
+761600428,西河镇人民政府,贵州凌宇建筑工程有限公司
+754143259,上海市嘉定工业区社区卫生服务中心,
+758644327,庐山市中小型水利工程集中建设项目部,江西昌丰建筑工程有限公司
+762692770,佛冈工业园管理委员会,清远市远业农业科技有限公司
+759516915,浙江省嘉兴市秀洲区嘉北街道金都社区居民委员会,嘉兴市大晶装饰工程有限公司
+761232401,云南省森林消防总队,北京华腾鑫业科技有限公司
+757700503,南方医科大学深圳医院,
+762718007,民和回族土族自治县巴州镇联合卫生院,河南腾雅医疗器械贸易有限公司
+760989323,合肥市农业农村局,
+754409355,广西金川公司,
+762650617,中国五冶集团有限公司,昆山红升起重设备有限公司
+762679500,中国第一重型机械股份公司,吉林省天勤机电安装工程有限公司
+754437973,中国交通信息科技集团有限公司,
+761068561,重庆恒昌旅游开发有限公司,重庆永渝检验检测技术有限公司
+762697621,霍山县自然资源和规划局,安徽省地质矿产勘查局313地质队
+762364538,湖北省发展和改革委员会,
+762085730,畜牧兽医技术服务中心,武汉晟宇天成建筑工程有限公司
+757813292,平阳县横阳控股有限公司,温州乾盛建设有限公司
+762652315,芮城县公安局交通管理大队,
+762648184,昭通学院,
+762686505,中通服咨询设计研究院有限公司,
+762173015,金湖县尧轩实业有限责任公司,金湖金尚电力实业开发有限公司
+762663510,哈尔滨东安汽车动力股份有限公司,北京发那科机电有限公司
+762417003,格盟岚县新能源有限责任公司,
+762670534,重庆市沙坪坝区陈家桥中心医院,
+762561537,铜陵理工学校,
+762404112,中国三冶集团有限公司冶金工程公司,
+762719023,新蔡县供销合作社,新蔡县水兴建筑工程有限公司
+762648507,河南神火国贸有限公司,
+762696022,江阴市华西建筑安装工程有限公司,江阴市恒奥工程技术有限公司
+762726034,江西畅行高速公路服务区开发经营有限公司驿购便利店分公司,
+762136002,巴彦县公路发展中心,黑龙江省宸阊路桥工程有限公司
+761651199,宿州市萧县生态环境分局,
+762722010,芜湖市龙山建设发展投资有限公司,
+762680536,南乐县总工会,南乐县宏基电脑科技部
+762690004,饶平县高堂镇人民政府,西桥设计有限公司
+762714034,中国五环工程有限公司,顺岑来管道工程(上海)有限公司
+760909806,镇沅彝族哈尼族拉祜族自治县勐大镇人民政府,普洱市镇沅新华书店有限公司
+762704029,阳泉煤业(集团)有限责任公司五矿,
+762666540,晋能控股装备制造集团有限公司,山西恒艺光影文化传媒有限公司
+762658656,贵州黔西红林矿业有限公司,贵州杨彬机械设备销售有限公司
+762169613,石家庄市裕华区城市管理综合行政执法局,北京宏远嘉泰建设集团有限公司
+762704033,成都航空有限公司,
+762658936,翁牛特旗农牧局,
+752562692,黄山市公路管理服务中心,
+751612272,龙泉市普耀电力有限责任公司,
+762157064,上海市浦东新区高行镇人民政府,上海立信佳诚东审会计师事务所有限公司
+762587637,安庆中船柴油机有限公司,南京绿航自动化科技有限公司
+762691715,中国电信海南公司,天泽智联科技股份公司
+762691531,泸定县公安局,
+762660020,广西路建工程集团有限公司二公司,广西毅力建筑工程有限公司
+762357560,锦州医科大学附属第一医院,
+762581525,定西市安定区农业农村局,
+762715021,浙江巨化化工材料有限公司,
+762142042,中国华润有限公司,
+762324523,常德市机关事务管理局,武陵区皇马汽车维修服务中心
+762472106,合肥市妇幼保健院,华润安徽医药有限公司
+762722026,金隅冀东水泥集团股份有限公司,
+762145024,兰州新区西岔中心卫生院,兰州奥昕广告有限公司
+762658512,鲁西化工集团股份有限公司煤化一分公司,凯特克集团有限公司
+761690148,中共金塔县委党校(金塔县行政学校),甘肃追梦文化传有限责任公司
+762590533,杭州市临平区乔司街道永西集体经济组织,
+762162038,遂宁市船山区中医医院,四川天荣诚产业发展集团有限责任公司
+762505025,天水市麦积区北道卫生院,天水正睿达商贸有限公司
+762183006,中南大学湘雅三医院,
+752920168,象州县石龙中心幼儿园,
+762690307,鸡西市鸡冠区红星乡人民政府,中国石油天然气股份有限公司黑龙江鸡西销售分公司
+762263056,西藏那曲比如县住房和城乡建设局,西藏迅通电梯工程有限公司
+762675502,大连理工大学,廊坊康鑫电子配件有限公司
+755212681,黄骅市中医医院,
+762678005,中广核检测技术有限公司,
+762676506,丹寨县人民代表大会常务委员会办公室,丹寨县尚唯科技中心
+752542461,河北高速集团通衢科技有限公司,
+762225059,陕西渭滨发展投资集团有限公司,中铁七局集团南京工程有限公司
+762177075,杭州市滨江区综合行政执法局,杭州诚道科技股份有限公司
+762137488,浚县农业农村局,河南广智农林生态有限公司
+762723004,天山材料股份有限公司,广元市吉泽建设工程有限公司
+762651512,龙山县石牌镇中心小学,华夏建弘设计集团有限公司
+762720557,中国石化国际事业有限公司,
+758140413,中国共产主义青年团四川省团校,成都灰狗运业(集团)有限公司
+762656550,大连高新技术产业园区龙王塘街道办事处,大连稼禾餐饮管理有限公司
+762217603,安徽省滁州市中级人民法院,
+762684026,义乌市地产发展有限公司,
+762691655,南阳市宛城区常庄小学校,中州梦建设集团有限公司
+762710739,农业发展服务中心,辽宁谦诺铭鑫会计师事务所
+762660500,西湖大学,南京晶萃光学科技有限公司
+762662656,中煤第三建设(集团)有限责任公司工程承包分公司,安徽国东再生资源有限公司
+762240116,汝阳县小店镇人民政府小店镇人民政府,
+762683000,中国电子科技集团公司第七研究所,
+762171575,余庆县重点水源保护服务中心,贵州冕瑞丰建设工程有限公司
+762680173,武穴市自然资源和规划局,武汉光谷环保科技股份有限公司
+762431069,伊犁哈萨克自治州人民检察院阿勒泰分院,阿勒泰鑫远征进口汽车维修有限公司
+761509868,界首市泉阳镇中心卫生院,
+762696006,石横特钢集团有限公司,
+762295580,烟台华润锦纶有限公司,
+762667514,云南东源镇雄煤业有限公司,
+762208602,山东鲁抗医药股份有限公司,
+762650702,济宁能源发展集团物资供应有限公司,荆州紫辰通信科技有限公司
+762657060,新余钢铁集团有限公司,国药控股新余有限公司
+762720004,信阳豫东南未来社区开发建设有限公司,中建新疆建工(集团)有限公司
+762693535,咸阳彩虹医院,宁夏普可医疗科技有限公司
+761744833,成都长城钨钼新材料有限责任公司,
+762654688,浙江浙能燃气股份有限公司,浙江华力市政工程有限公司
+762725009,重庆市荣昌仁义中学校,
+762678031,浙江大麦屿港务有限公司,浙江杜金环境科技有限公司
+762232260,烟台昆嵛山国家级自然保护区昆嵛镇人民政府,镇江禾林生物科技有限公司
+753379213,广西糖业集团平吉制糖有限公司,广西南宁尚云机电设备工程有限公司
+762186529,凉山甘洛全民健身中心,
+762705204,桐乡市大麻工业区开发有限公司,浙江鹏诚建设有限公司
+762723016,原州区第十一小学,宁夏万家源商贸有限公司
+762678043,福泉市人民检察院,贵州智能创新商贸有限公司
+761662858,安阳市融媒体中心,上海呈泽贸易有限公司
+756984426,浙江中南建设集团有限公司,
+752841174,浙江省地矿建设有限公司,浙江省国际合作旅行社有限公司
+762664681,四川宏源燃气股份有限公司,成都市三海热缩制品有限责任公司
+762407091,徐州中金棚户区改造建设有限公司,江苏科信工程咨询有限公司
+762660516,中铁建设集团南方工程有限公司,
+762654790,杭州师范大学附属医院(杭州市第二人民医院),杭州申华景观建设有限公司
+762100576,临潭县羊沙镇人民政府,临潭县弘昌建设工程有限责任公司
+762397086,定远县张桥镇人民政府,定远县鑫汇水利建筑工程有限公司
+762045695,山东恒盛建筑工程材料有限公司,
+762011012,湛江市大宇物业服务有限公司,日立电梯有限公司
+762671505,中共武汉市委办公厅,中国太平洋财产保险股份有限公司武汉中心支公司
+755094516,厦门市九溪高级中学,厦门元立凡教育科技有限公司
+762490524,中国核工业建设股份有限公司,中国核工业二四建设有限公司
+762086097,通江县力迅建设投资集团有限公司,
+762656534,山东山水水泥集团有限公司,
+762659503,连云港市赣榆区财政局,南京英绩博效风险评估咨询有限公司
+762076518,鹤壁煤业运输带有限责任公司,
+762660534,贵州金益煤炭开发有限公司,金沙万通商贸有限责任公司
+762693505,华南师范大学,
+751745567,大方县黄泥塘镇卫生院,
+760621761,贵州省博物馆,成都政通会计师事务所(普通合伙)
+762400534,桐乡市智汇生态产业开发有限公司,巨匠建设集团股份有限公司
+762179536,康乐县稼轩中学,
+762706500,敬业集团有限公司,河北博鑫重型装备配件制造有限公司
+762715009,内蒙古岱海发电有限责任公司,
+762645829,四川亚东水泥有限公司,
+762695524,上饶市广丰区市政公用设施投资开发有限责任公司,青岛国友咨询有限公司
+761938109,泾源县教育体育局,宁夏泾源县世纪购物中心商贸有限公司
+762680025,阜阳皖润电力有限公司,无锡朝建瑞机电设备有限公司
+762121567,富平县石川河管理总站,陕西省水工程勘察规划研究院
+762693030,宁乡市教育局,长沙盛唐体育用品有限公司
+762673034,中铁六局集团建筑安装工程有限公司,山西中正凯宏建材有限公司
+753074210,杭州市萧山区人民政府南阳街道办事处,
+762723526,重庆交通建设(集团)有限责任公司,
+762706510,中国邮电器材集团有限公司,广东金辉华集团有限公司
+762662002,上海市宝山区绿化建设和管理中心(上海吴淞炮台湾国家湿地公园管理中心),上海众园建筑工程有限公司
+762686697,中海油能源发展股份有限公司,
+762717020,哈尔滨工业大学,东北林业大学
+762357076,西安思创农业科技有限公司,陕西华茂建设监理咨询有限公司
+762707094,延安市宝塔区水利工作队,陕西凯实建设工程有限公司
+762318828,江苏雅迪科技发展有限公司,
+762601596,罗定市泷浚投资有限公司,爱建信达工程咨询有限公司
+762686507,金海钛业,
+762236009,安徽建工公路桥梁建设集团有限公司,
+762644527,中煤北京煤矿机械有限责任公司,河北宏策橡塑密封制品有限公司
+762229617,祁阳市职业中等专业学校,广州博厦建筑设计研究院有限公司
+762715017,大庆油田总医院,
+762715023,河南水投资源开发管理集团有限公司,
+756294892,临海市中医院,
+762669512,铜川市燃气和热力管理站,得力集团有限公司
+762670533,芜湖新兴铸管有限责任公司,
+762374066,中宁县大战场镇北滩完全小学,中宁县夏华商贸有限公司
+761615180,哈尔滨市南岗区人民政府,
+752975157,北京市石景山区园林绿化局,建研凯勃建设工程咨询有限公司
+762703010,广西玉林通和投资有限公司,广西博磊建筑工程有限公司
+762672511,长春净月高新技术产业开发区土地收购储备中心,
+758624062,东至县市场监督管理局,
+761501219,单州市城市管理局,徐州市政建设集团有限责任公司
+762661310,岑溪市公安局,广西盈科文化传播有限公司
+762670528,光采招标(深圳)有限公司,
+762297758,青川县第一人民医院,
+762670512,呼玛县北疆乡北疆村股份经济合作社,
+762713259,安徽医科大学第二附属医院,
+762682010,祥云县鹿鸣乡中心学校,祥云县荣科商贸有限责任公司
+762714032,南京市溧水区人民政府永阳街道办事处,南京信佣工程咨询有限公司
+762122233,东莞市农贸市场,
+761682826,聊城市传染病医院,山东九州通医疗器械有限公司
+762672169,陕西延长石油天然气股份有限公司,延安博怀建筑有限公司
+762646065,三明市三元区交通运输局,福建省捷庆信息技术有限公司
+762719515,广西北港不锈钢有限公司,
+762696335,南昌大学,江西宁伟科技有限公司
+762444040,信阳市公安交通警察支队,河南永和建设集团有限公司
+762669513,湖北能源集团新能源发展有限公司,北京中安质环技术评价中心有限公司
+762670169,山西路桥集团吕梁国道项目建设管理有限公司,山西路桥集团交通机电工程有限公司
+762725022,昆山市自来水集团有限公司,北京瑞柯膺斯策划咨询有限公司
+762661504,塔里木职业技术学院,上海萃思软件有限公司
+762676031,塔什库尔干塔吉克自治县塔合曼乡人民政府,塔什库尔干昆仑建材有限公司
+750864928,华创天元实业发展有限责任公司,
+762129462,四川瑞迪森检测技术有限公司,
+762160070,安徽江东文旅康养集团有限公司,安徽创美环境工程有限公司
+762669548,浙江数智交院科技股份有限公司,中达建筑设计有限公司
+762716033,安徽华电芜湖发电有限公司,四川润泰特种气体有限公司
+762701289,抚顺矿业集团有限责任公司,
+762654021,峡江新奥燃气有限公司,
+760931189,常州市新北区绿化废弃物处置中心,
+762124004,际华三五零二职业装有限公司,
+762693035,阜宁县古河镇人民政府,江苏梦利天建设工程有限公司
+761918596,邵阳市大祥区农业农村局,
+762672703,深圳市水务(集团)有限公司罗湖分公司,深圳市环水管网科技服务有限公司
+762675641,中国银联股份有限公司,上海锦丽华建筑装潢工程有限公司
+762654534,哈尔滨锅炉厂有限责任公司,江阴创捷电气设备有限公司
+762714521,国家粮食四川交易中心,
+762243062,察布查尔锡伯自治县交通运输局,
+762512556,临海市大洋街道双桥村股份经济合作社,泰昌建设有限公司
+761134870,中国共产党陈巴尔虎旗委员会统一战线工作部,陈巴尔虎旗巴彦库仁镇云海印刷厂
+762643006,重庆市自来水有限公司,
+762694506,,北京双子建筑工程有限公司
+762138551,中铁建大桥工程局集团第四工程有限公司,
+762695517,中共湖州市委党校(湖州市行政学院、湖州市社会主义学院、浙江生态文明干部学院),江苏博思维光电集团有限公司
+762654026,三亚市人民医院(三亚市人民医院医疗集团总院),
+762720034,中化重庆涪陵化工有限公司,
+762146408,贵州义龙(集团)投资管理有限公司,
+762167117,莱西市人民法院,太平财产保险有限公司青岛分公司
+762721000,如东县袁庄镇海河滩村股份经济合作社,
+762439553,珠海市公安局,广州竞远安全技术股份有限公司
+762662103,镇江港国际集装箱码头有限公司,南京犇驰装饰工程有限公司
+762332095,河北南和经济开发区管理委员会,中铁城际规划建设有限公司
+762216608,深圳理工大学总医院,中国电信股份有限公司深圳分公司
+762364599,贵州省医疗保障局,
+752796710,天津万事兴诚房地产开发有限责任公司,天津锦程电力技术有限公司
+762705506,华电能源股份有限公司牡丹江第二发电厂,
+762199082,中化二建集团有限公司,
+759648825,宁乡市卫生健康局,
+762703022,凉山州绿恒燃气有限公司,江汉油田瑞腾达工程潜江有限公司
+762696909,常山县招贤镇人民政府,浙江焱丰建设有限公司
+762683527,山西潞安华亿实业有限公司,浙江晋绣能源化工有限公司
+761703271,山东省统计科学研究所,滨州市住房和城乡建设局
+762715804,邛崃市市场监督管理局,中国平安财产保险股份有限公司成都中心支公司
+758540785,青岛国际邮轮港区航运中心,
+762678004,贵州省遵义监狱,
+761253291,大连海事大学附属学校,大连滨采供应链管理有限公司
+751188392,厦门市翔安火炬实验学校,厦门萱斩艺园艺有限公司
+762679027,浙江浙能长兴发电有限公司,
+762315068,马边星农现代农业开发有限公司,
+762646532,湖北航鹏化学动力科技有限责任公司,
+762701022,甘肃中瑞铝业有限公司,
+762167785,当阳市城市管理执法局,中国石化销售股份有限公司湖北宜昌石油分公司
+762688199,江西晶昊盐化有限公司,江西优赛科技有限公司
+760182085,安吉县人武部营院,
+762697020,靖江市信华建设有限公司,
+762156053,山东港口日照港集团有限公司,中铁工程设计咨询集团有限公司
+762655625,广西柳州格瑞米智能装备制造有限公司,柳州市博运金属加工有限责任公司
+762705004,河北太行机械工业有限公司,
+762690505,中铁二十二局集团有限公司哈尔滨分公司,
+762701731,长沙市土地储备中心,长沙泰安保安服务有限公司
+762675515,东莞市塘厦镇石鼓股份经济联合社,
+762192616,新沂市住房和城乡建设局,江苏丛泰建设工程管理有限公司
+760878277,郴州市公共资源交易中心,
+762699566,东关小学,
+762648178,渤海钻探泥浆技术服务分公司,宝石花产业经营服务有限公司
+762114097,河南省农业农村厅,
+757565946,广东省深圳市福田区新世界山月居业主大会,
+762675589,抚松县公路建设管理中心,吉林省交通规划设计院
+750697343,国网山东电力威海供电公司,
+751124366,广州地铁集团,中国铁建电气化局
+762339608,萧县人民医院,
+762659342,大唐云南发电有限公司,
+762702540,柳林县翔威新能源有限公司,山西德尔雅环保科技有限公司
+762696548,青海机场有限公司,青海和谐物业管理有限公司
+762695636,山西地宝能源有限公司,山西长桥科技有限公司
+762143502,重庆广阳湾人才服务有限公司,
+762656510,安乡县机关事务服务中心,安乡县潺陵汽修厂
+762663045,陕西省应急管理厅,西安飞杰电子科技有限公司
+762169118,石家庄市城市更新促进中心,
+762118038,荣成市精宜海洋科技股份有限公司,
+762461532,淮北市市政工程管理处,中煤特殊凿井有限责任公司
+762577200,内蒙古包钢钢联股份有限公司,内蒙古泽洋机电科技有限公司
+752447655,宁波湾区开发集团有限责任公司,
+762649526,中国石化集团胜利石油管理局有限公司临盘服务协调站,胜利油田德利实业有限责任公司
+762687029,荣成市第三十五中学,荣成市宜广贸易有限公司
+762656036,中铁十一局集团有限公司,
+758055801,国网山东省电力公司,
+762468073,上海金茂建筑装饰有限公司,
+762682536,福建优胜招标项目管理集团有限公司,
+762653132,国家电投集团江西电力有限公司分宜发电厂,苏州探微机电有限公司
+755689474,青岛市崂山区人民政府王哥庄街道办事处,
+761162060,吉林市住房和城乡建设局,
+762712518,亳州市谯城区双沟学区中心学校,亳州市金龙彩印包装有限公司
+762329605,中山聯成化學工業有限公司,
+762723269,中国航发北京航空材料研究院,
+761353614,安庆市中医医院(安庆医药高等专科学校附属医院),
+762645018,上海局集团公司上铁机辆公司芜湖车辆分公司,芜湖县清水高强度紧固件有限公司
+762703030,和龙万润新厂,河北东润建设集团有限公司
+762694682,宁夏回族自治区自然资源信息中心,
+762707006,上海飞机制造有限公司,上海建科消防技术有限公司
+762644508,青岛市殡葬事业服务中心(青岛市殡仪馆),青岛华通捷汽车维修有限公司
+762299524,,
+762656023,汕头大学,杭州创印科技有限公司
+762695258,,浙江博誉建设有限公司
+762259610,草湖项目区自然资源和规划服务中心,
+762588657,中节能风力发电四川有限公司,瑞科同创电力工程设计有限公司
+762095591,天津能源投资集团有限公司,
+762374551,南昌大学第二附属医院,
+762683034,中海油能源发展股份有限公司,
+757769062,龙岩市中医院,龙岩市华维医疗器械有限公司
+762702882,浙江省一建建设集团有限公司,
+762670131,中央储备粮太原直属库有限公司平定分公司,纵横九州路桥建设有限公司
+762665001,衡阳华菱钢管有限公司,深圳市爱特爱科技有限公司
+762706642,广西壮族自治区国有七坡林场,
+762259501,云阳盐化有限公司,
+762653018,安徽马钢输送设备制造有限公司,
+762684029,昆明云能化工有限公司,深圳市中电电力技术股份有限公司
+762689319,鸿舰公司,
+762659001,南京医科大学第二附属医院,江苏明生医疗科技有限公司
+762496039,深圳大学,
+761185413,山东青年政治学院,
+760959072,贺州市生态环境局,
+751059575,海珠区文化馆,广州市西亚兴安商业有限公司
+762366568,九江市林业局,广东双木林科技有限公司
+762667017,深圳市水务(集团)有限公司南山分公司,
+762578108,蒙牛乳业,夏县众为蓝图环保科技有限公司
+762614032,鞍钢国贸攀枝花有限公司,费斯托(中国)有限公司
+762386590,南通市崇川区城市工程建设管理中心,
+762130638,绍兴市上虞区卫生健康局,浙江华通云数据科技有限公司
+762678899,化州深能环保有限公司,东莞市瑞宏化工有限公司
+760947864,连州市温氏畜牧有限公司,
+762631001,长沙市中心医院,华润润心(湖南)医疗器械有限公司
+762654478,云和县中等职业技术学校,金华市龙恒水利工程有限公司
+762650500,淮安市淮安区住房和城乡建设局,
+762657536,武汉钢铁集团物流有限公司,
+754487193,福建省龙岩卫生学校,福建鑫安消防检测有限公司
+762655720,日照市公路事业发展中心,莒县鼎辰物业服务有限公司
+762588532,乌海包钢矿业有限责任公司,包头市诚信达工程咨询监理有限责任公司
+762702523,多氟多新材料股份有限公司,
+762367089,佛山市高明区荷城街道城建综合事务中心,中融合纵工程设计有限公司
+762698012,中交一公局集团有限公司,
+762351080,蚌埠市中心血站,蚌埠宝源文化传媒有限公司
+753312128,苏州融园资产经营有限公司,
+762720025,宁波市奉化区振西城建开发有限公司,
+762687030,天河热电分公司,石河子开发区成辉商贸有限公司
+762299086,龙门县龙华镇人民政府,龙门县产投建筑工程有限公司
+756414484,铜陵市中心血站,唐山启奥科技股份有限公司
+762399526,天长市大通镇中心卫生院,
+762680034,福建华佳彩有限公司,
+762631679,山南市自然资源局,
+762658509,深圳实验学校,
+760957816,西安元新航天动力流体装备有限公司,
+762333639,海南省直属机关服务中心,广州智业节能科技有限公司
+753711144,中国雄安集团智慧能源有限公司,北京市勘察设计研究院有限公司
+762677601,安徽水安建设集团股份有限公司,安徽雅丽建设集团有限公司
+762699501,江口县交通运输局,铜仁交旅集团交通工程试验检测有限公司
+762383518,广州市越德企业管理咨询有限公司,
+762703000,重庆市江南城市建设发展(集团)有限公司,重庆快致科技有限公司
+762672022,中节能(大城)环保能源有限公司,大城县卓越广告有限公司
+762662019,云南驰宏资源综合利用有限公司,
+762701195,国网四川电力送变电建设有限公司,四川健程通达物流有限公司
+762134048,达州建工集团有限公司,四川华地会计师事务所有限责任公司
+761969162,中国电建集团河北工程有限公司,内蒙古科瑞房地产土地资产评估有限公司
+756039507,田东县农业农村局,广西西大检测有限公司
+762711023,中盐(内蒙古)碱业有限公司,奈曼旗本恒五金销售有限公司
+758472944,广东省中山市古镇镇曹口村民委员会,广东南春市政建设工程有限公司
+762689013,青岛市即墨区田横卫生院,青岛鹏程伟业商贸有限公司
+762678522,中海油田服务股份有限公司,江苏如通石油机械股份有限公司
+762293610,吴江经济技术开发区建设局,江苏省交通工程集团有限公司
+762240058,阆中惠帮路桥建设有限公司,顺安建筑设计咨询集团有限公司
+762655006,太原钢铁(集团)金属回收加工贸易有限公司,山西科盛通机电工程有限公司
+761133250,青岛市技师学院,威海东来旺餐饮管理有限公司
+762679335,安徽省宁国市津北中心小学,安徽吉智建设工程有限公司
+753279400,深圳市宝安区人民医院,
+762721524,凌云县直属机关第一幼儿园,百色市硕德厨房设备工程有限公司
+762370010,杭州市上城区水墩股份经济合作社,浙江上安建设有限公司
+762679619,陕西煤业物资有限责任公司西安分公司,北京康斯特仪表科技股份有限公司
+762182597,国能南部生物发电有限公司,
+762718030,青海省妇幼保健院,青海金珠药业有限公司
+762700639,重庆盛世桃源物业管理有限公司,重庆千万加建设工程有限公司
+762655568,中国石油天然气股份有限公司吉林石化分公司,浙江伦特机电有限公司
+762290004,山西省眼科医院,
+762641721,沈阳铁道信息科技有限公司,百信信息技术有限公司
+762701025,厦门金鹭特种合金有限公司,
+762704526,南京师范大学,
+758050410,武汉市黄陂区人民政府滠口街道办事处,
+762718020,连云港鸿云实业有限公司,
+762696009,江阴利港发电股份有限公司,江阴市宇棣物资有限公司
+762419571,邵阳市生态环境局新邵分局,湖南新安检测技术有限公司
+762472500,东菀市友腾电子科技有限公司,
+762696018,淮安市洪泽区金色家园小区物业管理委员会,碧桂园生活服务集团股份有限公司
+762677664,江苏徐矿能源股份有限公司物资供销分公司,山东成亮水泵制造有限公司
+762702004,宁波慈溪工贸集团有限公司,浙江中弘检测技术有限公司
+762176562,福建省金海水产发展有限公司,
+762606911,湛江市第二十七中学,广东百基保安服务有限公司
+758344617,广西电网有限责任公司玉林供电局,
+762678041,郑州航空港汇港发展有限公司,河南空港磬德科技有限公司
+762718003,广东粤华发电有限责任公司,广州松佳机电设备有限公司
+762676006,江苏省市场监督管理实训技术研究院,南京砚敏至臻信息科技有限公司
+762718014,闽清县白中镇攸太村股份经济合作社,
+762272562,新昌县根治欠薪领导小组办公室,
+762680506,淳化县农业农村局,陕西博隆建设工程有限公司
+762704761,襄州区张湾街道办事处政府,湖北众强智宏商贸有限公司
+758774947,重庆润文商贸有限责任公司,重庆市铜梁区博弘丰商贸有限公司
+762709166,萍乡经济技术开发区城市管理服务中心,中犇工程设计有限公司
+762703031,中国石油工程建设有限公司,沧州市金实工程技术有限公司
+762183309,重庆市石柱土家族自治县西沱中学校,重庆佐恩家具有限公司
+762673035,中蓝晨光化工有限公司,
+762348725,宁乡市第十一高级中学,湖南沿湖建设工程有限公司
+762694515,湖北工业大学,深圳市北科商贸有限公司
+761495372,新乡市平原城乡一体化示范区管理委员会林水局,
+762693541,上海辰华网络技术服务有限公司,
+762523569,杭州职业技术大学,
+762193064,歙县农村公路管理服务中心,宁夏交通建设股份有限公司
+762242538,葫芦岛市现代农业发展服务中心,葫芦岛冠旗商贸有限公司
+762689519,四平市中心人民医院,
+762707022,西北恒辉(内蒙古)电子材料科技有限公司,中国电子系统工程第四建设有限公司
+762663524,西北农林科技大学,杨凌卓晟腾跃化玻仪器经营部
+762129721,河南省发展和改革委员会,
+762102016,海口市路桥建设投资有限公司,海口市设计集团有限公司
+762172010,大健康事业部,
+762694522,东风井关农业机械有限公司,武汉凡迪信息技术有限公司
+762601654,遂宁柔刚投资集团有限公司,四川宝飞建设工程有限公司
+762113508,武汉汉能电力发展有限公司,
+762660838,中海油深圳海洋工程技术服务有限公司,江苏润邦工业装备有限公司
+762704093,深圳市机场(集团)有限公司,深圳市标驰信息技术有限公司
+762571003,海尔集团,
+762384042,北京世源希达工程技术有限公司,
+762695673,宁波市北仑区公共建设工程有限公司,宁波市测绘和遥感技术研究院(宁波市自然资源和规划调查监测中心)
+757081350,广西广林森林资源产业投资集团有限公司,广西林业集团桂江勘测设计有限公司
+762679621,郑州德润市政工程有限公司,郑州郑荣压力容器有限公司
+762176050,绥江县中城镇人民政府,中国石化销售股份有限公司云南昭通石油分公司
+762679002,新兴县疾病预防控制中心,
+762311554,襄阳市新华游乐公园事务中心,
+762528598,绵阳市安州区中医院,
+761411593,福建省金龙稀土股份有限公司,
+762498021,若羌东新新能源有限公司,
+761024693,遵义市汇川区第十九小学,贵州仲立商贸有限公司
+762349574,寿县茶庵镇人民政府,寿县农一电子商务有限公司
+755762151,四川德鑫建设工程咨询有限公司,
+762670009,平和县疾病预防控制中心,
+762722519,中国电信股份有限公司苏州分公司,江苏天诺网络科技有限公司
+762629035,昌吉市机关事务服务中心,昌吉市新零点百货超市
+753030414,江西铜业民爆矿服有限公司,
+762697624,重庆市潼南区公安局,潼南区潼双一分厂汽车维修服务场(个体工商户)
+762698005,景津装备股份有限公司,
+762692107,汉源县公安局,中国人民财产保险股份有限公司雅安市分公司
+759330640,湖北鄂州鄂城区城市建设投资有限公司,
+762285093,阿勒泰地区社会主义学院,阿勒泰东东商贸有限公司
+762274831,石家庄市行政审批局(石家庄市政务服务管理办公室),华北制药集团爱诺有限公司
+762663530,云南锡业集团物流有限公司,
+762720525,西南大学,中国电信股份有限公司北碚分公司
+762722135,中国河南国际合作集团有限公司,
+762693209,安徽省皖北煤电集团有限责任公司,江苏中仑建设科技有限公司
+762654522,中国煤炭地质总局第四水文地质队,河北怀道贸易有限公司
+762318813,内江市经济和信息化局,
+762687032,驻马店市白云纸业有限公司,平顶山市金利达物资有限公司
+762702522,北京市药品检验研究院(北京市疫苗检验中心),
+762672501,华安县汰口农垦农业发展有限公司,
+762597522,进贤县林业局,江西省鹏锦园林有限公司
+762680513,贵州黔铭物资贸易有限公司,
+762685531,航天科工哈尔滨风华有限公司电站设备分公司,哈尔滨华创弦柯电气有限公司
+762188548,丹霞冶炼厂,
+761297800,中国能源建设集团新疆电力设计院有限公司,
+757120047,秦皇岛佰工钢铁有限公司,
+761353896,胶州市自然资源和规划局,
+762724503,松溪县教育局,
+762653721,浙江交科供应链管理有限公司,浙江国自机器人技术股份有限公司
+762662022,连云港市交通技工学校,
+762680515,麟游县官坪幼儿园,
+762450668,浙江巨元矿业有限公司,
+762707170,呼和浩特市光源电力安装有限责任公司,锡林郭勒盟伊荣清真肉食品有限责任公司
+762194541,拜泉县卫生健康局,
+762249031,天津市宁河区潘庄镇朱头淀小学,天津市宁河县旺盛通达商贸中心
+754195446,青岛市水务管理局,
+752862039,安徽省马鞍山市博望区丹阳镇小花津社区居民委员会,马鞍山润兴农业发展有限公司
+762713522,中国共产党苏尼特左旗委员会党校,苏尼特左旗满达物业服务有限责任公司
+762640511,亳州市谯城区观堂镇中心卫生院,亳州市拓达网络科技有限责任公司
+762594017,磴口县住房和城乡规划建设局,
+751925994,深圳市第二人民医院,
+758076921,肇庆市第二人民医院新院,
+761045515,四川兰丰工程设计有限公司,四川武阳安腾建筑工程有限公司
+762705532,绛县南樊镇中心卫生院(绛县医疗集团南樊镇中心卫生院),绛县惠维商贸有限公司
+754830315,深圳大学总医院,
+762665731,山西省中阳荣欣焦化有限公司,
+762087179,文成县国有资产投资经营有限公司,
+762684027,江苏高速公路工程养护有限公司,江苏宁凯建设工程有限公司
+762706513,珠海市交通运输安全事务中心(珠海市路桥管理处),
+754326927,南安市乐峰镇炉星村民委员会,
+758105096,商飞软件有限公司,中佳信建设管理集团有限公司
+762700522,光泽县李坊乡岩岭资产营运公司,光泽县君州园林工程有限公司
+761299041,宁城县林业和草原局,
+761153693,中国重汽集团济南卡车股份有限公司,
+762687493,弥勒市太平街道牛背社区居民委员会,
+762704038,肥东县水务局,安徽中正建设有限公司
+760949503,海南省技师学院(海南省高级技工学校、海南省高级技术学校),海南佰为科技有限公司
+762716024,包头市九原区文体旅游广电局,包头市木星广告传媒有限公司
+762583507,上海亚新城市建设有限公司,上海华东房产设计院有限公司
+762412064,济南迪亚实业有限责任公司,
+762677521,山西医科大学第一医院交城分院,山西环宇建筑工程有限公司
+762718519,杭州市钱塘区市场监督管理局(杭州市钱塘区知识产权局),
+757898855,安徽芸果生物技术有限公司,
+762595504,榆中县夏官营镇太平堡村集体经济组织,
+762089583,重庆大学,
+762601731,泊头市文化广电和旅游局,
+762716755,平利县民政局,
+762316027,无锡市蠡湖弘瑞物业管理服务有限公司,无锡市顺昌物业有限公司
+762114541,广东环境保护工程职业学院,广东蓝天大学生就业市场经营有限公司

BIN
qwen_lora/data_files/招标人标注_260414.xlsx


BIN
qwen_lora/data_files/赛默飞-样例数据.xlsx


+ 205 - 0
qwen_lora/finetune_sft.py

@@ -0,0 +1,205 @@
+import gc
+import os
+import sys
+
+# 必须在任何 import 之前
+
+os.environ["TRANSFORMERS_OFFLINE"] = "1"
+os.environ["HF_DATASETS_OFFLINE"] = "1"
+os.environ["CUDA_VISIBLE_DEVICES"] = "1"
+
+os.environ["TORCHDYNAMO_DISABLE"] = "1"
+os.environ["TORCH_COMPILE_DISABLE"] = "1"
+os.environ["UNSLOTH_DISABLE_COMPILE"] = "1"
+os.environ["TRITON_DISABLE_COMPILE"] = "1"
+
+# 禁用 Triton 的 persistent TMA(针对你的警告)
+os.environ["TRITON_ENABLE_PERSISTENT_TMA_MATMUL"] = "0"
+os.environ["TORCH_COMPILE_DISABLE"] = "1"
+
+os.environ["UNSLOTH_SKIP_VLLM_CHECK"] = "1"
+
+import torch
+import torch.nn as nn
+# 现在可以安全导入 Unsloth
+from unsloth import FastLanguageModel
+from unsloth.chat_templates import train_on_responses_only
+from trl import SFTTrainer, SFTConfig
+from transformers import DataCollatorForLanguageModeling
+
+from load_data import load_bid_data
+
+
+# 定义缺少的 set_submodule 方法
+def set_submodule(model, target, module):
+    if "." not in target:
+        setattr(model, target, module)
+    else:
+        parent_name, child_name = target.rsplit(".", 1)
+        parent = model.get_submodule(parent_name)
+        setattr(parent, child_name, module)
+
+
+# 强行把这个方法注入到 nn.Module 基类里,一劳永逸
+if not hasattr(nn.Module, "set_submodule"):
+    nn.Module.set_submodule = set_submodule
+
+project_dir = os.path.abspath(os.path.dirname(__file__)) + '/../'
+MAX_SEQ_LENGTH = int(1024 * 16)
+
+train_data_path = project_dir + 'qwen_0.8B_lora_bidding_kg/data7_prefix_aug/train_data.jsonl'
+dev_data_path = project_dir + 'qwen_0.8B_lora_bidding_kg/data7_prefix/dev_data.jsonl'
+train_data_path1 = project_dir + 'qwen_0.8B_lora_bidding_kg/data4_prefix_aug/train_data.jsonl'
+dev_data_path1 = project_dir + 'qwen_0.8B_lora_bidding_kg/data4_prefix/dev_data.jsonl'
+train_data_path2 = project_dir + 'qwen_0.8B_lora_bidding_kg/data5_prefix/train_data.jsonl'
+dev_data_path2 = project_dir + 'qwen_0.8B_lora_bidding_kg/data5_prefix/dev_data.jsonl'
+train_data_path3 = project_dir + 'qwen_0.8B_lora_bidding_kg/data6_prefix_aug/train_data.jsonl'
+dev_data_path3 = project_dir + 'qwen_0.8B_lora_bidding_kg/data6_prefix/dev_data.jsonl'
+
+
+PER_DEVICE_TRAIN_BATCH_SIZE = 2  # 单卡批次大小,16G GPU建议2-4
+GRADIENT_ACCUMULATION_STEPS = 2  # 梯度累积,弥补批次小的问题
+MODEL_NAME = '/home/user/.cache/huggingface/hub/models--Qwen--Qwen3.5-0.8B/snapshots/2fc06364715b967f1860aea9cf38778875588b17/'
+OUTPUT_DIR = project_dir + "qwen_0.8B_lora_bidding_kg/lora-sft"  # 微调结果保存路径
+checkpoint_path = project_dir + "qwen_0.8B_lora_bidding_kg/trainer_output/checkpoint-380"
+
+print('context length', MAX_SEQ_LENGTH)
+
+# 加载模型时显式禁用编译
+model, tokenizer = FastLanguageModel.from_pretrained(
+    model_name=MODEL_NAME,
+    max_seq_length=MAX_SEQ_LENGTH,
+    dtype=torch.bfloat16,
+    load_in_4bit=True,
+)
+
+print('model_type', model.config.model_type)
+
+# 添加 LoRA(不使用任何 compile)
+r = 16
+model = FastLanguageModel.get_peft_model(
+    model,
+    r=r,
+    # target_modules=["q_proj", "v_proj", ],
+    target_modules=["q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj"],
+    lora_alpha=r*2,
+    lora_dropout=0.1,
+    use_gradient_checkpointing="unsloth",
+)
+
+# 手动确保没有 compile
+if hasattr(torch, "compile"):
+    torch.compile = lambda x, *args, **kwargs: x
+
+
+print(f"Allocated1: {torch.cuda.memory_allocated(0) / 1024 ** 3:.2f} GB")
+print('\n 加载数据 \n')
+
+train_dataset, dev_dataset = load_bid_data(
+    [train_data_path, train_data_path1, train_data_path2, train_data_path3],
+    [dev_data_path, dev_data_path1, dev_data_path2, dev_data_path3]
+)
+
+
+# 只计算answer部分的loss
+response_template = "<|im_start|>assistant\n"
+response_ids = tokenizer.encode(response_template, add_special_tokens=False)
+print(f"Template IDs: {response_ids}")
+
+
+def truncate_eval_dataset(example):
+    # 使用 tokenizer 对文本进行截断
+    tokens = tokenizer(
+        example["text"], # 或者是你数据中的 key,如 "prompt" + "answer"
+        truncation=True,
+        max_length=2048, # 评估强制限制在 2k
+        add_special_tokens=True,
+    )
+    # 将截断后的 token 重新转回文本,或者直接返回 token
+    return {"text": tokenizer.decode(tokens["input_ids"], skip_special_tokens=False)}
+
+# 处理验证集
+dev_dataset = dev_dataset.map(truncate_eval_dataset)
+
+# 创建 Trainer
+# 更改源码 unsloth trainer.py is_vlm = False,才能packing
+trainer = SFTTrainer(
+    model=model,
+    # output_dir=OUTPUT_DIR,
+    tokenizer=tokenizer,
+    train_dataset=train_dataset,
+    eval_dataset=dev_dataset,
+    max_seq_length=MAX_SEQ_LENGTH,
+    args=SFTConfig(
+        learning_rate=2e-5,
+        output_dir=OUTPUT_DIR,
+        warmup_steps=5,
+        num_train_epochs=4,
+        per_device_train_batch_size=PER_DEVICE_TRAIN_BATCH_SIZE,
+        gradient_accumulation_steps=GRADIENT_ACCUMULATION_STEPS,
+        fp16=False,
+        bf16=True,
+        optim="adamw_8bit",
+        # 关键:禁用所有编译相关选项
+        torch_empty_cache_steps=1,
+        dataloader_num_workers=0,  # 避免多进程问题
+        dataset_num_proc=1,
+        save_steps=1024,
+        save_strategy="steps",
+        seed=3407,
+        save_total_limit=3,  # 最多保存3个检查点
+
+        weight_decay=0.01,
+        lr_scheduler_type="cosine",
+
+        logging_steps=1024,
+
+        eval_strategy="steps",
+        eval_steps=1024,
+        per_device_eval_batch_size=1,
+        eval_accumulation_steps=1,
+        do_eval=True,
+        metric_for_best_model="eval_loss",
+        greater_is_better=False,
+        prediction_loss_only=True,
+        load_best_model_at_end=True,
+    ),
+
+)
+
+num_train_samples = len(trainer.train_dataset)
+print(f"*** Packing 后的总样本数: {num_train_samples} ***")
+
+max_len = max(len(x) for x in trainer.train_dataset["input_ids"])
+print(f"训练集最大 Token 长度: {max_len}")
+
+# 简单测试代码
+sample_batch = next(iter(trainer.get_train_dataloader()))
+# 统计一下非 -100 的 token 占比,确保不是 0
+non_ignore = (sample_batch["labels"] != -100).sum().item()
+total = sample_batch["labels"].numel()
+print(f"有效 Loss Token 占比: {non_ignore / total:.2%}, {non_ignore}, {total}")
+
+# 只计算回答loss
+trainer = train_on_responses_only(
+    trainer,
+    instruction_part="<|im_start|>user\n",
+    response_part="<|im_start|>assistant\n",
+)
+
+print('确认数据', tokenizer.decode(trainer.train_dataset[10]["input_ids"]))
+
+print('只有回答', tokenizer.decode(
+    [tokenizer.pad_token_id if x == -100 else x for x in trainer.train_dataset[10]["labels"]]).replace(
+    tokenizer.pad_token, " "))
+
+model.gradient_checkpointing_enable()
+
+
+trainer.train()
+
+# 继续训练 由于torch2.5有bug,内核升不了2.6,暂时不支持继续训练
+# trainer.train(resume_from_checkpoint=checkpoint_path)
+
+model.save_pretrained(OUTPUT_DIR)
+tokenizer.save_pretrained(OUTPUT_DIR)

+ 1950 - 0
qwen_lora/get_data.py

@@ -0,0 +1,1950 @@
+import json
+import random
+import re
+import traceback
+from compare_utils import getUnifyMoney
+import pandas as pd
+from bs4 import BeautifulSoup
+
+random.seed(112)
+
+bid_cols_dict = {
+    "project_name": "项目名称",
+    "project_code": "项目编号",
+    "docchannel": "公告类型",
+    "area": "地域",
+    "province": "省",
+    "city": "市",
+    "district": "区",
+    "tenderee": "招标人",
+    "tenderee_contact": "招标人联系人",
+    "tenderee_phone": "招标人联系人电话",
+    "agency": "代理人",
+    "agency_contact": "代理人联系人",
+    "agency_phone": "代理人联系人电话",
+    "sub_docs_json": "多标段信息",
+    "products": "产品信息",
+    "service_time": "开工竣工时间",
+    "time_bidstart": "投标开始时间",
+    "time_bidclose": "截标时间",
+    "time_bidopen": "开标时间",
+    "time_get_file_end": "文件获取截止时间",
+    "time_get_file_start": "文件获取开始时间",
+    "time_release": "发布时间",
+    "time_registration_end": '报名截止时间',
+    "time_registration_start": "报名开始时间",
+    "time_earnest_money_end": "保证金递交截止时间",
+    "time_earnest_money_start": "保证金递交开始时间",
+}
+
+print('cols', bid_cols_dict.keys())
+
+channel_map_dict = {
+    51: "公告变更",
+    52: "招标公告",
+    101: "中标信息",
+    102: "招标预告",
+    103: "招标答疑",
+    104: "招标文件",
+    105: "资审结果",
+    106: "法律法规",
+    107: "新闻资讯",
+    108: "拟建项目",
+    109: "展会推广",
+    110: "企业名录",
+    111: "企业资质",
+    112: "全国工程人员",
+    113: "业主采购",
+    114: "采购意向",
+    115: "拍卖出让",
+    116: "土地矿产",
+    117: "产权交易",
+    118: "废标公告",
+    119: "候选人公示",
+    120: "合同公告",
+    121: "开标记录",
+    122: "验收合同",
+    301: "拟在建项目",
+    302: "审批项目",
+    303: "处罚公告",
+}
+
+sub_docs_json_map_dict = {
+    "sub_project_name": "标包项目名称",
+    "sub_project_code": "标包项目编号",
+    "bidding_budget": "预算金额",
+    "bidding_budget_unit": "预算金额单位",
+    "win_tenderer": "中标人",
+    "second_tenderer": "第二候选人",
+    "third_tenderer": "第三候选人",
+    "win_tenderer_manager": "中标人联系人",
+    "second_tenderer_manager": "第二候选人联系人",
+    "third_tenderer_manager": "第三候选人联系人",
+    "win_tenderer_phone": "中标人联系人电话",
+    "second_tenderer_phone": "第二候选人联系人电话",
+    "third_tenderer_phone": "第三候选人联系人电话",
+    "win_bid_price": "中标人投标金额",
+    "second_bid_price": "第二候选人投标金额",
+    "third_bid_price": "第三候选人投标金额",
+    "win_bid_price_unit": "中标人投标金额单位",
+    "second_bid_price_unit": "第二候选人投标金额单位",
+    "third_bid_price_unit": "第三候选人投标金额单位",
+}
+
+products_map_dict = {
+    'brand': '品牌',
+    'product': '产品名称',
+    'quantity': '数量',
+    'quantity_unit': '数量单位',
+    'specs': '规格',
+    'unitPrice': '单价',
+    "parameter": "参数",
+    "total_price": "总价",
+    "pinmu_no": "品目编号",
+    "pinmu_name": "品目名称",
+}
+
+
+def filter_data_docid():
+    df = pd.read_excel(r'D:\BIDI_DOC\比地_文档\export_260309.xlsx')
+    # data_list = df.astype(object).where(pd.notnull(df), "").values.tolist()
+    data_list = df[['docid', 'sub_docs_json']].astype(object).where(pd.notnull(df), "").values.tolist()
+    print('data_list[0]', data_list[0])
+    data_list.sort(key=lambda x: str(x[1]), reverse=True)
+    data_list = data_list[:5000]
+    for d in data_list[:20]:
+        print('d', d)
+    ss = json.dumps([x[0] for x in data_list])
+    with open(r'D:\BIDI_DOC\比地_文档\export_260309.txt', 'w') as f:
+        f.write(ss)
+    print('finish')
+
+
+def xlsx_data_to_jsonl():
+    df2 = pd.read_excel(r'D:\BIDI_DOC\比地_文档\export_260309_2.xlsx')
+    data_list2 = df2.astype(object).where(pd.notnull(df2), "").values.tolist()
+    filter_docid_dict = {int(x[0]): x[1] for x in data_list2}
+
+    df = pd.read_excel(r'D:\BIDI_DOC\比地_文档\export_260309.xlsx')
+    data_list = df.astype(object).where(pd.notnull(df), "").values.tolist()
+
+    all_data = []
+    instruction = '提取以上招投标文档的关键信息,只输出有值的,其中中标人等放在多标段信息中形成数组,' \
+                  '产品参数等放在产品信息中形成数组' \
+                  '金额均以元为单位,时间格式为YYYY-MM-DD HH:MM:SS,无多余内容' \
+                  '直接得到要素提取Json:'
+    for line in data_list:
+        docid = int(line[0])
+        if docid not in filter_docid_dict:
+            continue
+
+        doctextcon = filter_docid_dict.get(docid)
+
+        try:
+            channel = int(line[3])
+            channel = channel_map_dict.get(channel)
+            line[3] = channel
+        except:
+            print('channel error continue', line[3])
+            continue
+
+        # print('line[2]', line[2])
+        # print('line[14]', line[14])
+        # print('line[15]', line[15])
+        # print('line[16]', line[16])
+
+        if not line[14]:
+            line[14] = []
+        else:
+            sub_docs_json = json.loads(line[14])
+            for si, d1 in enumerate(sub_docs_json):
+                d1 = {v: d1.get(k, "") for k, v in sub_docs_json_map_dict.items()}
+                sub_docs_json[si] = d1
+
+            for si, sub in enumerate(sub_docs_json):
+                delete_k = []
+                for k, v in sub.items():
+                    if not v:
+                        delete_k.append(k)
+                for k in delete_k:
+                    if k in sub:
+                        sub.pop(k)
+                sub_docs_json[si] = sub
+
+            line[14] = sub_docs_json
+
+        if not line[15] or len(line[15]) >= 500:
+            line[15] = []
+        else:
+            products = json.loads(line[15])
+            for si, d1 in enumerate(products):
+                d1 = {v: d1.get(k, "") for k, v in products_map_dict.items()}
+                products[si] = d1
+            line[15] = products
+
+        if not line[16]:
+            line[16] = {}
+        else:
+            service_time = json.loads(line[16])
+            line[16] = service_time
+
+        d = {bid_cols_dict.get(x): line[i+1] for i, x in enumerate(bid_cols_dict.keys())}
+
+        # 删掉空字段
+        delete_k = []
+        for k, v in d.items():
+            if not v:
+                delete_k.append(k)
+        for k in delete_k:
+            if k in d:
+                d.pop(k)
+
+        train_data = {
+            "instruction": instruction,
+            "input": doctextcon,
+            "output": d
+        }
+        all_data.append(json.dumps(train_data, ensure_ascii=False))
+
+
+    # 生成
+    train_ratio = 0.8
+    dev_ratio = 0.1
+
+    random.shuffle(all_data)
+    total = len(all_data)
+    train_num = int(total * train_ratio)
+    dev_num = int(total * dev_ratio)
+
+    # 拆分
+    train_lines = all_data[:train_num]
+    dev_lines = all_data[train_num:train_num+dev_num]
+    test_lines = all_data[train_num+dev_num:]
+
+    # 保存
+    train_path = "data/train_data.jsonl"
+    dev_path = "data/dev_data.jsonl"
+    test_path = "data/test_data.jsonl"
+    with open(train_path, 'w', encoding='utf-8') as f:
+        f.write("\n".join(train_lines))
+    with open(dev_path, 'w', encoding='utf-8') as f:
+        f.write("\n".join(dev_lines))
+    with open(test_path, 'w', encoding='utf-8') as f:
+        f.write("\n".join(test_lines))
+
+
+def extract_json_to_psv(_dict, empty_char=''):
+    """
+    json转竖线格式
+
+    :return:
+    """
+    # empty_char = 'null'
+
+    project_name = _dict.get('name')
+
+    float_none_list = ['0', '0.0', 'None', empty_char, '', '未提及']
+
+    district_dict = _dict.get('district')
+    if not district_dict:
+        district_dict = {}
+    # 生成 PSV 表头(字段名)和数据行
+    headers = "|".join(district_dict.keys())
+    values = "|".join(str(value) for value in district_dict.values())
+
+    # 拼接成完整 PSV 内容
+    psv_content = f"{headers}\n{values}"
+
+    prem = _dict.get('prem')
+    tenderee = ""
+    tenderee_contact_list = []
+    agency = ""
+    win_tenderer_info_list = []
+    for package_name, package_dict in prem.items():
+        bid_name = package_dict.get('name')
+        tenderee_money = package_dict.get('tendereeMoney')
+        tenderee_money_unit = package_dict.get('tendereeMoneyUnit')
+        role_list = package_dict.get('roleList')
+        project_code = package_dict.get('code')
+
+        if str(tenderee_money) in float_none_list:
+            tenderee_money = empty_char
+            tenderee_money_unit = empty_char
+        else:
+            tenderee_money_unit = '元'
+
+        if package_name == 'Project':
+            package_name = empty_char
+
+        win_tenderer_info = None
+        for role_dict in role_list:
+            role_type = role_dict.get('role_name')
+            role_text = role_dict.get('role_text')
+            contact_list = role_dict.get('linklist', [])
+
+            role_money = role_dict.get('role_money', {}).get('money')
+            role_money_unit = role_dict.get('role_money', {}).get('money_unit')
+
+            if str(role_money) in float_none_list:
+                role_money = empty_char
+                role_money_unit = empty_char
+            else:
+                role_money_unit = '元'
+
+            if role_type == 'tenderee' and len(role_text) >= 2:
+                tenderee = role_text
+                tenderee_contact_list += contact_list
+            if role_type == 'agency' and len(role_text) >= 2:
+                agency = role_text
+            if not win_tenderer_info and role_type == 'win_tenderer':
+                # if len(str(role_money)) > 0 and not role_money_unit:
+                #     role_money_unit = '元'
+                # if len(str(tenderee_money)) > 0 and not tenderee_money_unit:
+                #     tenderee_money_unit = '元'
+
+                win_tenderer_info = [package_name, project_code, role_text,
+                                     role_money, role_money_unit,
+                                     tenderee_money, tenderee_money_unit
+                                     ]
+                win_tenderer_info_list.append(win_tenderer_info)
+
+    product_list = _dict.get('product_attrs', {}).get('data', {})
+    product_cols = ['product', 'brand', 'specs', 'quantity',
+                    'unitPrice', 'total_price', 'pinmu_name', 'pinmu_no'
+                    ]
+    # print('product_list1', product_list)
+    product_list = [[x.get(y, "") for y in product_cols] for x in product_list]
+    # print('product_list2', product_list)
+    for pi, product in enumerate(product_list):
+        if str(product[3]) in float_none_list:
+            product_list[pi][3] = empty_char
+        if str(product[4]) in float_none_list:
+            product_list[pi][4] = empty_char
+        if str(product[5]) in float_none_list:
+            product_list[pi][5] = empty_char
+
+
+    table_list = []
+    # table 1
+    table_cols = ['项目名称', '招标人名称', '代理人名称']
+    table_values = [[project_name, tenderee, agency]]
+    table_list.append([table_cols, table_values])
+
+    # table 2
+    table_cols = ['招标人联系人', '招标人联系人电话']
+    # print('tenderee_contact_list', tenderee_contact_list)
+    table_values = tenderee_contact_list if tenderee_contact_list else []
+    table_list.append([table_cols, table_values])
+
+    # table 3
+    table_cols = ['标段名称', '标段号', '中标人名称', '中标金额', '中标金额单位', '标段预算', '标段预算单位']
+    table_values = win_tenderer_info_list if win_tenderer_info_list else []
+    table_list.append([table_cols, table_values])
+
+    # table 4
+    table_cols = ['产品名称', '品牌', '规格型号', '数量', '单价', '总价', '品目名称', '品目编号']
+    table_values = product_list if product_list else []
+    table_list.append([table_cols, table_values])
+
+    final_str = ''
+    show_flag = 0
+    for table_cols, table_values in table_list:
+        str1 = '|'.join(table_cols) + '\n'
+
+        continue_flag = 0
+
+        if table_values:
+            str2 = ''
+            if len(table_values) >= 2:
+                # print('table_values', table_values)
+                show_flag = 1
+            for line in table_values:
+                if '|' in str(line):
+                    continue_flag = 1
+                    break
+                str2 += '|'.join([str(x) if str(x) != '' else empty_char for x in line]) + '\n'
+            if not str2:
+                str2 = '|'.join([empty_char for x in table_cols]) + '\n'
+        else:
+            str2 = '|'.join([empty_char for x in table_cols]) + '\n'
+
+        if continue_flag:
+            return None
+
+        # 判断表头和内容竖线是否相同
+        # for ss2 in str2.split('\n'):
+        #     if len(ss2) == 0:
+        #         continue
+        #     if len(re.findall("\|", str1)) != len(re.findall("\|", ss2)):
+        #         print('--- str1', str1)
+        #         print('--- str2', ss2)
+        #         return None
+
+        if len(re.findall("\|", str2)) % len(re.findall("\|", str1)) != 0:
+            print('--- str1', str1)
+            print('--- str2', str2)
+            return None
+
+        final_str += str1
+        final_str += str2
+        final_str += '\n'
+
+    # if f'产品名称|品牌|规格型号|数量|单价|总价|品目名称|品目编号\n{empty_char}|{empty_char}|{empty_char}|{empty_char}|{empty_char}|{empty_char}|{empty_char}' in final_str and f'标段名称|标段号|中标人名称|中标金额|中标金额单位|标段预算|标段预算单位\n{empty_char}|{empty_char}|{empty_char}|{empty_char}|{empty_char}|{empty_char}|{empty_char}' in final_str:
+    #     return None
+
+    final_str = re.sub('未提及', f'{empty_char}', final_str)
+
+    delete_value_list = ['None', '无', '无品牌', '无型号']
+    for v in delete_value_list:
+        final_str = re.sub(f'\|{v}\|', f'|{empty_char}|', final_str)
+        final_str = re.sub(f'\|{v}\n', f'|{empty_char}\n', final_str)
+        final_str = re.sub(f'\n{v}\|', f'\n{empty_char}|', final_str)
+
+    # if show_flag:
+    #     print('final_str', final_str)
+    # final_str = table_list_to_psv(table_list, empty_char)
+    return final_str
+
+
+def extract_json_to_psv_prefix(_dict, text, empty_char='-', prefix='[全字段]'):
+    """
+    json转竖线格式
+
+    :return:
+    """
+    # empty_char = 'null'
+
+    project_name = _dict.get('name')
+
+    float_none_list = ['0', '0.0', 'None', empty_char, '', '未提及']
+
+    district_dict = _dict.get('district')
+    if not district_dict:
+        district_dict = {}
+    # 生成 PSV 表头(字段名)和数据行
+    headers = "|".join(district_dict.keys())
+    values = "|".join(str(value) for value in district_dict.values())
+
+    # 拼接成完整 PSV 内容
+    psv_content = f"{headers}\n{values}"
+
+    prem = _dict.get('prem')
+    tenderee = ""
+    tenderee_contact_list = []
+    agency = ""
+    win_tenderer_info_list = []
+    for package_name, package_dict in prem.items():
+        bid_name = package_dict.get('name')
+        tenderee_money = package_dict.get('tendereeMoney')
+        tenderee_money_unit = package_dict.get('tendereeMoneyUnit')
+        role_list = package_dict.get('roleList')
+        project_code = package_dict.get('code')
+
+        if str(tenderee_money) in float_none_list:
+            tenderee_money = empty_char
+            tenderee_money_unit = empty_char
+        else:
+            tenderee_money_unit = '元'
+
+        if package_name == 'Project':
+            package_name = empty_char
+
+        win_tenderer_info = None
+        for role_dict in role_list:
+            role_type = role_dict.get('role_name')
+            role_text = role_dict.get('role_text')
+            contact_list = role_dict.get('linklist', [])
+
+            role_money = role_dict.get('role_money', {}).get('money')
+            role_money_unit = role_dict.get('role_money', {}).get('money_unit')
+
+            if str(role_money) in float_none_list:
+                role_money = empty_char
+                role_money_unit = empty_char
+            else:
+                role_money_unit = '元'
+
+            if role_type == 'tenderee' and len(role_text) >= 2:
+                tenderee = role_text
+                tenderee_contact_list += contact_list
+            if role_type == 'agency' and len(role_text) >= 2:
+                agency = role_text
+            if not win_tenderer_info and role_type == 'win_tenderer':
+                # if len(str(role_money)) > 0 and not role_money_unit:
+                #     role_money_unit = '元'
+                # if len(str(tenderee_money)) > 0 and not tenderee_money_unit:
+                #     tenderee_money_unit = '元'
+
+                win_tenderer_info = [package_name, project_code, role_text,
+                                     role_money, role_money_unit,
+                                     tenderee_money, tenderee_money_unit
+                                     ]
+                win_tenderer_info_list.append(win_tenderer_info)
+
+    product_list = _dict.get('product_attrs', {}).get('data', {})
+    product_cols = ['product', 'brand', 'specs', 'quantity',
+                    'unitPrice', 'total_price', 'pinmu_name', 'pinmu_no'
+                    ]
+    # print('product_list1', product_list)
+    product_list = [[x.get(y, "") for y in product_cols] for x in product_list]
+    # print('product_list2', product_list)
+    for pi, product in enumerate(product_list):
+        if str(product[3]) in float_none_list:
+            product_list[pi][3] = empty_char
+        if str(product[4]) in float_none_list:
+            product_list[pi][4] = empty_char
+        if str(product[5]) in float_none_list:
+            product_list[pi][5] = empty_char
+
+    if prefix == '[全字段]':
+
+        table_list = []
+        # table 1
+        table_cols = ['项目名称', '招标人名称', '代理人名称']
+        table_values = [[project_name, tenderee, agency]]
+        table_list.append([table_cols, table_values])
+
+        # table 2
+        table_cols = ['招标人联系人', '招标人联系人电话']
+        # print('tenderee_contact_list', tenderee_contact_list)
+        table_values = tenderee_contact_list if tenderee_contact_list else []
+        temp_list = []
+        for v in table_values:
+            if (v[0] not in [None, '', '-'] and v[0] in text) \
+                    or (v[1] not in [None, '', '-'] and v[1] in text):
+                temp_list.append(v)
+        table_values = temp_list
+        table_list.append([table_cols, table_values])
+
+        # table 3
+        table_cols = ['标段名称', '标段号', '中标人名称', '中标金额', '中标金额单位', '标段预算', '标段预算单位']
+        table_values = win_tenderer_info_list if win_tenderer_info_list else []
+        temp_list = []
+        for v in table_values:
+            if (v[0] not in [None, '', '-'] and v[0] in text) \
+                    or (v[2] not in [None, '', '-'] and v[2] in text) \
+                    or (v[1] not in [None, '', '-'] and v[1] in text):
+                temp_list.append(v)
+        table_values = temp_list
+        table_list.append([table_cols, table_values])
+
+        # table 4
+        table_cols = ['产品名称', '品牌', '规格型号', '数量', '单价', '总价', '品目名称', '品目编号']
+        table_values = product_list if product_list else []
+        temp_list = []
+        for v in table_values:
+            if v[0] not in [None, '', '-'] and v[0] in text:
+                temp_list.append(v)
+        table_values = temp_list
+
+        # # 产品中数值类型 重复3次
+        # for v in table_values:
+        #     for col_i in [3, 4, 5]:
+        #         try:
+        #             col_v = float(v[col_i])
+        #             if col_v > 0:
+        #                 v[col_i] = ','.join([v[col_i], v[col_i], v[col_i]])
+        #         except:
+        #             pass
+
+        table_list.append([table_cols, table_values])
+
+        # final_str = ''
+        # show_flag = 0
+        # for table_cols, table_values in table_list:
+        #     str1 = '|'.join(table_cols) + '\n'
+        #
+        #     continue_flag = 0
+        #
+        #     if table_values:
+        #         str2 = ''
+        #         if len(table_values) >= 2:
+        #             # print('table_values', table_values)
+        #             show_flag = 1
+        #         for line in table_values:
+        #             if '|' in str(line):
+        #                 continue_flag = 1
+        #                 break
+        #             str2 += '|'.join([str(x) if str(x) != '' else empty_char for x in line]) + '\n'
+        #         if not str2:
+        #             str2 = '|'.join([empty_char for x in table_cols]) + '\n'
+        #     else:
+        #         str2 = '|'.join([empty_char for x in table_cols]) + '\n'
+        #
+        #     if continue_flag:
+        #         return None
+        #
+        #     # 判断表头和内容竖线是否相同
+        #     # for ss2 in str2.split('\n'):
+        #     #     if len(ss2) == 0:
+        #     #         continue
+        #     #     if len(re.findall("\|", str1)) != len(re.findall("\|", ss2)):
+        #     #         print('--- str1', str1)
+        #     #         print('--- str2', ss2)
+        #     #         return None
+        #
+        #     if len(re.findall("\|", str2)) % len(re.findall("\|", str1)) != 0:
+        #         print('--- str1', str1)
+        #         print('--- str2', str2)
+        #         return None
+        #
+        #     final_str += str1
+        #     final_str += str2
+        #     final_str += '\n'
+        #
+        # # if f'产品名称|品牌|规格型号|数量|单价|总价|品目名称|品目编号\n{empty_char}|{empty_char}|{empty_char}|{empty_char}|{empty_char}|{empty_char}|{empty_char}' in final_str and f'标段名称|标段号|中标人名称|中标金额|中标金额单位|标段预算|标段预算单位\n{empty_char}|{empty_char}|{empty_char}|{empty_char}|{empty_char}|{empty_char}|{empty_char}' in final_str:
+        # #     return None
+        #
+        # final_str = re.sub('未提及', f'{empty_char}', final_str)
+        #
+        # delete_value_list = ['None', '无', '无品牌', '无型号']
+        # for v in delete_value_list:
+        #     final_str = re.sub(f'\|{v}\|', f'|{empty_char}|', final_str)
+        #     final_str = re.sub(f'\|{v}\n', f'|{empty_char}\n', final_str)
+        #     final_str = re.sub(f'\n{v}\|', f'\n{empty_char}|', final_str)
+        #
+        # # if show_flag:
+        # #     print('final_str', final_str)
+
+        final_str = table_list_to_psv(table_list, empty_char)
+        # final_str = '[全字段]' + final_str
+        final_str = prefix + final_str
+        return final_str
+
+    elif prefix == '[仅招标人]':
+        if not tenderee:
+            return None
+
+        sen_list = re.findall('[^,。;?!\n]+[,。;?!\n]?', text)
+        tenderee_sen_list = []
+        for sen in sen_list:
+            match = re.search(re.escape(tenderee), sen)
+            if match:
+                tenderee_sen_list.append(sen)
+        if tenderee_sen_list:
+            tenderee_sen_list.sort(key=lambda x: len(x))
+            tenderee_line = tenderee_sen_list[0]
+        else:
+            tenderee_line = empty_char
+
+        table_list = []
+        table_cols = ['招标人', '招标人表达']
+        table_values = [[tenderee, tenderee_line]]
+        table_list.append([table_cols, table_values])
+
+        final_str = table_list_to_psv(table_list, empty_char)
+        if not final_str:
+            return final_str
+        final_str = prefix + final_str
+        return final_str
+        # answer = f'[仅招标人]招标人|招标人表达\n{tenderee}|{tenderee_line}'
+        # return answer
+
+    elif prefix == '[仅产品]':
+        table_cols = ['产品名称', '品牌', '规格型号', '数量', '单价', '总价', '品目名称', '品目编号']
+        table_values = product_list if product_list else []
+
+        temp_list = []
+        for v in table_values:
+            if v[0] not in [None, '', '-'] and v[0] in text:
+                temp_list.append(v)
+        table_values = temp_list
+
+        # # 产品中数值类型 重复3次
+        # for v in table_values:
+        #     for col_i in [3, 4, 5]:
+        #         try:
+        #             col_v = float(v[col_i])
+        #             if col_v > 0:
+        #                 v[col_i] = ','.join([v[col_i], v[col_i], v[col_i]])
+        #         except:
+        #             pass
+
+        table_list = []
+        table_list.append([table_cols, table_values])
+        final_str = table_list_to_psv(table_list, empty_char)
+        if not final_str:
+            return final_str
+        final_str = prefix + final_str
+        return final_str
+
+
+def entity_to_psv_prefix(text, entity, empty_char='-', prefix='[仅招标人]'):
+    if not entity:
+        return None
+
+    sen_list = re.findall('[^,。;?!\n]+[,。;?!\n]?', text)
+    tenderee_sen_list = []
+    for sen in sen_list:
+        match = re.search(re.escape(entity), sen)
+        if match:
+            tenderee_sen_list.append(sen)
+    if tenderee_sen_list:
+        tenderee_sen_list.sort(key=lambda x: len(x))
+        tenderee_line = tenderee_sen_list[0]
+    else:
+        tenderee_line = empty_char
+    if prefix == '[仅招标人]':
+        answer = f'{prefix}招标人|招标人表达\n{entity}|{tenderee_line}'
+    elif prefix == '[全字段]':
+        answer = f'{prefix}项目名称|招标人名称|代理人名称\n-|{entity}|-' \
+                 f'\n\n招标人联系人|招标人联系人电话\n-|-' \
+                 f'\n\n标段名称|标段号|中标人名称|中标金额|中标金额单位|标段预算|标段预算单位\n-|-|-|-|-|-|-' \
+                 f'\n\n产品名称|品牌|规格型号|数量|单价|总价|品目名称|品目编号\n-|-|-|-|-|-|-|-'
+    return answer
+
+
+def psv_to_dict(_str):
+#     _str = '''
+# 项目名称|招标人名称|代理人名称
+# 英吉沙县技工学校关于身体按摩的网上超市采购项目|英吉沙县技工学校|-
+#
+# 招标人联系人|招标人联系人电话
+# -|17690175536
+#
+# 标段名称|标段号|中标人名称|中标金额|中标金额单位|标段预算|标段预算单位
+# 1|-|喀什市兆佳文体用品商行|3175.0|元|-|元
+#
+# 产品名称|品牌|规格型号|数量|单价|总价|品目名称|品目编号
+# 刮痧板 刮痧版 身体按摩|无品牌|刮痧板|15|17.0|255.0|-|-
+# 口红 彩妆|无品牌|口红|15|17.0|255.0|-|-
+# 卸妆棉 彩妆|无品牌|卸妆棉|15|17.0|255.0|-|-
+# 卸妆水 彩妆|无品牌|卸妆水|15|33.0|495.0|-|-
+# 定妆粉 彩妆|无品牌|定妆粉|15|18.0|270.0|-|-
+# BB霜 隔离霜|无品牌|BB霜|15|35.0|525.0|-|-
+# 01眼影 眼霜|无品牌|01|15|35.0|525.0|-|-
+# 洁丽雅洗面奶 洁面用品|洁丽雅/grace|洗面奶|15|33.0|495.0|-|-
+# 00115454凯伦特/CARENT棉签 棉签/棉棒/棉包|凯伦特/CARENT|00115454|8|5.0|40.0|-|-
+# 祝源梳子 梳子/化妆梳/按摩梳|祝源|梳子|15|4.0|60.0|-|-
+# '''
+
+    # 去掉前缀指示
+    _str = re.sub('\[全字段\]|\[仅招标人\]', '', _str)
+
+    table_head_list = [
+        '项目名称|招标人名称|代理人名称',
+        '招标人联系人|招标人联系人电话',
+        '标段名称|标段号|中标人名称|中标金额|中标金额单位|标段预算|标段预算单位',
+        '产品名称|品牌|规格型号|数量|单价|总价|品目名称|品目编号',
+    ]
+
+    has_all_head_flag = 1
+    for head in table_head_list:
+        if head not in _str:
+            has_all_head_flag = 0
+            break
+
+    if not has_all_head_flag:
+        return {}
+
+    # 按空行分割成4个PSV块
+    blocks = [b.strip() for b in _str.split("\n\n") if b.strip()]
+
+    # 定义字段映射(和你的4段格式严格对应)
+    keys = [
+        "招标信息",
+        "招标人联系方式",
+        "中标信息",
+        "产品信息",
+    ]
+
+    # 批量解析
+    result = {}
+    for key, block in zip(keys, blocks):
+        dict_list = psv_block_to_dict(block)
+
+        # 产品重复3次只保留第一个
+        num_cols = ['单价', '数量', '总价']
+        if key in ['产品信息']:
+            for d in dict_list:
+                for col in num_cols:
+                    v = d.get(col)
+                    if v and ',' in v:
+                        d[col] = v.split(',')[0]
+
+        result[key] = dict_list
+
+    # print('result', result)
+    return result
+
+
+def psv_block_to_dict(block):
+    """
+    把单个 PSV 块(表头+数据行)转换成字典
+    支持:1行数据 / 多行数据(自动转列表)
+    """
+    lines = [line.strip() for line in block.strip().splitlines() if line.strip()]
+    if len(lines) < 2:
+        return {}
+
+    # 解析表头和数据行
+    headers = [h.strip() for h in lines[0].split("|")]
+    data_rows = [[d.strip() if d != '-' else '' for d in line.split("|")] for line in lines[1:]]
+
+    # 多行 → 列表套字典,单行 → 单层字典
+    # if len(data_rows) == 1:
+    #     return dict(zip(headers, data_rows[0]))
+    return [dict(zip(headers, row)) for row in data_rows]
+
+
+def psv_to_dict_prefix(_str):
+
+    # 去掉前缀指示
+    _str = re.sub('\[全字段\]|\[仅招标人\]', '', _str)
+
+    table_head_list = [
+        '招标人|招标人表达',
+    ]
+
+    has_all_head_flag = 1
+    for head in table_head_list:
+        if head not in _str:
+            has_all_head_flag = 0
+            break
+
+    if not has_all_head_flag:
+        return {}
+
+    line_list = _str.split('\n')
+
+    temp_list = []
+    for line in line_list:
+        if '|' not in line:
+            continue
+        temp_list.append(line)
+    line_list = temp_list
+
+    # line_list = line_list[1:]
+
+    # print('line_list[1]', line_list[1])
+    tenderee, tenderee_sentence = line_list[1].split('|')[:2]
+
+    result = {'招标信息': {'招标人名称': tenderee}}
+
+    # print('result', result)
+    return result
+
+
+def html2text_with_table_html(_html, limit=10000):
+    # 如果输入是字符串,使用 BeautifulSoup 解析
+    if isinstance(_html, str):
+        _html = re.sub("<html>|<body>|</body>|</html>","",_html)
+        _soup = BeautifulSoup(_html, "lxml")
+    else:
+        _soup = _html
+
+    # 用于存储处理后的文本
+    result_parts = []
+
+    _find = False
+    # 遍历所有直接子元素
+    for child in _soup.contents:
+        # print('child.name', child.name)
+        if child.name:
+            if child.name in ["table", "tbody"]:
+                #仅仅保存rowspan和colspan属性的标签
+                for c in child.find_all():
+                    new_attrs = {}
+                    for k,v in c.attrs.items():
+                        if k in ["rowspan","colspan"]:
+                            new_attrs[k] = v
+                    c.attrs = new_attrs
+
+                # 如果是表格或表格主体,保留 HTML 代码
+                result_parts.append("\n"+str(child)+"\n")
+            else:
+                # 递归处理其他元素并转换为文本
+                text = html2text_with_table_html(child)
+                if child.name in {"p","div","li"}:
+                    text += '\n'
+                result_parts.append(text)
+        elif child.string and child.string.strip():
+            _text = child.string.strip()
+            result_parts.append(_text)
+        _find = True
+
+    # print('result_parts', result_parts)
+
+    # if not _find:
+    #     print('not find')
+    #     _text = str(_soup.get_text())
+    #     print('_text', _text)
+    #     if len(_text)>0:
+    #         print('_soup.name', _soup.name)
+    #         if _soup.name in {"p","div","li"}:
+    #             print('yes')
+    #             _text += "\n"
+    #         result_parts.append(_text)
+
+    # 将所有处理后的部分连接成一个字符串
+    result = "".join(result_parts)
+    result = result[:limit]
+    return result
+
+
+def xlsx_data_to_jsonl_2():
+    df1 = pd.read_csv(r'D:\BIDI_DOC\比地_文档\export_ai_260323_2.csv')
+    df2 = pd.read_excel(r'D:\BIDI_DOC\比地_文档\export_ai_260323_2_extract.xlsx')
+    data_list1 = df1.astype(object).where(pd.notnull(df1), "").values.tolist()
+    data_list2 = df2.astype(object).where(pd.notnull(df2), "").values.tolist()
+    docid_html_dict = {int(x[0]): x[1] for x in data_list1}
+    docid_json_dict = {int(x[0]): x[1] for x in data_list2}
+
+    all_data = []
+    instruction = '根据上述招投标行业公告,进行要素提取,输出psv格式:\n'
+
+    empty_char = '-'
+    instruction = f"""
+你是招投标要素抽取专家。
+请严格按下面PSV格式输出,禁止修改表头,空字段置为{empty_char},字段之间用|分隔,首尾不加|。
+
+项目名称|招标人名称|代理人名称
+
+招标人联系人|招标人联系人电话
+
+标段名称|标段号|中标人名称|中标金额|中标金额单位|标段预算|标段预算单位
+
+产品名称|品牌|规格型号|数量|单价|总价|品目名称|品目编号
+
+请抽取以上内容并严格按上述4段PSV输出: 
+"""
+
+    for line in data_list1:
+        docid = int(line[0])
+
+        html = docid_html_dict.get(docid)
+        extract_json = docid_json_dict.get(docid)
+
+        text = html2text_with_table_html(html)
+        try:
+            answer = extract_json_to_psv(json.loads(extract_json), empty_char=empty_char)
+            if answer is None:
+                continue
+        except:
+            continue
+
+        train_data = {
+            "instruction": instruction,
+            "input": text,
+            "output": answer,
+        }
+        all_data.append(json.dumps(train_data, ensure_ascii=False))
+
+    # 生成
+    train_ratio = 0.8
+    dev_ratio = 0.1
+
+    random.shuffle(all_data)
+    total = len(all_data)
+    train_num = int(total * train_ratio)
+    dev_num = int(total * dev_ratio)
+
+    # 拆分
+    train_lines = all_data[:train_num]
+    dev_lines = all_data[train_num:train_num+dev_num]
+    test_lines = all_data[train_num+dev_num:]
+
+    print('len(train_lines)', len(train_lines))
+    print('len(test_lines)', len(test_lines))
+
+    # 保存
+    train_path = "data2/train_data.jsonl"
+    dev_path = "data2/dev_data.jsonl"
+    test_path = "data2/test_data.jsonl"
+    with open(train_path, 'w', encoding='utf-8') as f:
+        f.write("\n".join(train_lines))
+    with open(dev_path, 'w', encoding='utf-8') as f:
+        f.write("\n".join(dev_lines))
+    with open(test_path, 'w', encoding='utf-8') as f:
+        f.write("\n".join(test_lines))
+
+
+def xlsx_data_to_jsonl_3():
+    df1 = pd.read_csv(r'D:\BIDI_DOC\比地_文档\export_ai_260327_2.csv')
+    df2 = pd.read_csv(r'C:\Users\Administrator\Downloads\document_tmp_has_ai_no_attachment_260327_limit.csv')
+    data_list1 = df1.astype(object).where(pd.notnull(df1), "").values.tolist()
+    data_list2 = df2.astype(object).where(pd.notnull(df2), "").values.tolist()
+    docid_html_dict = {int(x[0]): x[1] for x in data_list1}
+    docid_json_dict = {int(x[0]): x[-1] for x in data_list2}
+
+    all_data = []
+    # instruction = '根据上述招投标行业公告,进行要素提取,输出psv格式:\n'
+
+    empty_char = '-'
+    instruction = f"""
+你是招投标要素抽取专家。
+请严格按下面PSV格式输出,禁止修改表头,空字段置为{empty_char},字段之间用|分隔,首尾不加|。
+
+项目名称|招标人名称|代理人名称
+
+招标人联系人|招标人联系人电话
+
+标段名称|标段号|中标人名称|中标金额|中标金额单位|标段预算|标段预算单位
+
+产品名称|品牌|规格型号|数量|单价|总价|品目名称|品目编号
+
+请抽取以上内容并严格按上述4段PSV输出:
+"""
+
+
+    for line in data_list1:
+        docid = int(line[0])
+
+        html = docid_html_dict.get(docid)
+        extract_json = docid_json_dict.get(docid)
+
+        text = html2text_with_table_html(html)
+        try:
+            answer = extract_json_to_psv(json.loads(extract_json), empty_char=empty_char)
+            if answer is None:
+                continue
+        except:
+            continue
+
+        train_data = {
+            "instruction": instruction,
+            "input": text,
+            "output": answer,
+        }
+        all_data.append(json.dumps(train_data, ensure_ascii=False))
+
+    # 生成
+    train_ratio = 1.
+    dev_ratio = 0.
+
+    random.shuffle(all_data)
+    total = len(all_data)
+    train_num = int(total * train_ratio)
+    dev_num = int(total * dev_ratio)
+
+    # 拆分
+    train_lines = all_data[:train_num]
+    dev_lines = all_data[train_num:train_num+dev_num]
+    test_lines = all_data[train_num+dev_num:]
+
+    print('len(train_lines)', len(train_lines))
+    print('len(test_lines)', len(test_lines))
+
+    # 保存
+    train_path = "data3/train_data.jsonl"
+    dev_path = "data3/dev_data.jsonl"
+    test_path = "data3/test_data.jsonl"
+    with open(train_path, 'w', encoding='utf-8') as f:
+        f.write("\n".join(train_lines))
+    with open(dev_path, 'w', encoding='utf-8') as f:
+        f.write("\n".join(dev_lines))
+    with open(test_path, 'w', encoding='utf-8') as f:
+        f.write("\n".join(test_lines))
+
+
+def xlsx_data_to_jsonl_4_prefix():
+    df1 = pd.read_excel(r'D:\BIDI_DOC\比地_文档\260403_ai_人工标注_招标人表达_3_再人工_html.xlsx')
+    df2 = pd.read_excel(r'train_excel/260403_ai_人工标注_招标人表达_3_再人工.xlsx')
+    data_list1 = df1.astype(object).where(pd.notnull(df1), "").values.tolist()
+    data_list2 = df2.astype(object).where(pd.notnull(df2), "").values.tolist()
+    docid_html_dict = {int(x[0]): x[1] for x in data_list1}
+    docid_json_dict = {int(x[0]): [x[1], x[2]] for x in data_list2}
+
+    all_data = []
+
+    empty_char = '-'
+    instruction = f"""
+你是招投标要素抽取专家。
+请严格按下面PSV格式输出,禁止修改表头,空字段置为{empty_char},字段之间用|分隔,首尾不加|。
+
+招标人|招标人表达
+
+请抽取以上内容并严格按上述1段PSV输出: 
+"""
+
+    for line in data_list1:
+        docid = int(line[0])
+
+        html = docid_html_dict.get(docid)
+        tenderee_line, tenderee = docid_json_dict.get(docid)
+
+        if len(tenderee) <= 1:
+            tenderee = '-'
+        if len(tenderee_line) <= 1:
+            tenderee_line = '-'
+
+        text = html2text_with_table_html(html)
+        answer = f'[仅招标人]招标人|招标人表达\n{tenderee}|{tenderee_line}'
+
+        train_data = {
+            "instruction": instruction,
+            "input": text,
+            "output": answer,
+        }
+        all_data.append(json.dumps(train_data, ensure_ascii=False))
+
+    # 生成
+    train_ratio = 0.9
+    dev_ratio = 0.1
+
+    random.shuffle(all_data)
+    total = len(all_data)
+    train_num = int(total * train_ratio)
+    dev_num = int(total * dev_ratio)
+
+    # 拆分
+    train_lines = all_data[:train_num]
+    dev_lines = all_data[train_num:train_num+dev_num]
+    test_lines = all_data[train_num+dev_num:]
+
+    print('len(train_lines)', len(train_lines))
+    print('len(dev_lines)', len(dev_lines))
+
+    # 保存
+    train_path = "data4_prefix/train_data.jsonl"
+    dev_path = "data4_prefix/dev_data.jsonl"
+    test_path = "data4_prefix/test_data.jsonl"
+    with open(train_path, 'w', encoding='utf-8') as f:
+        f.write("\n".join(train_lines))
+    with open(dev_path, 'w', encoding='utf-8') as f:
+        f.write("\n".join(dev_lines))
+    with open(test_path, 'w', encoding='utf-8') as f:
+        f.write("\n".join(test_lines))
+
+
+def xlsx_data_to_jsonl_5():
+    df1 = pd.read_excel(r'D:\BIDI_DOC\比地_文档\260403_ai_人工标注_招标人表达_3_再人工_html.xlsx')
+    df2 = pd.read_excel(r'D:\BIDI_DOC\比地_文档\260403_ai_人工标注_招标人表达_3_再人工_json.xlsx')
+    df3 = pd.read_excel(r'D:\BIDI_DOC\比地_文档\260403_ai_人工标注_招标人表达_3_再人工.xlsx')
+    data_list1 = df1.astype(object).where(pd.notnull(df1), "").values.tolist()
+    data_list2 = df2.astype(object).where(pd.notnull(df2), "").values.tolist()
+    data_list3 = df3.astype(object).where(pd.notnull(df3), "").values.tolist()
+    docid_html_dict = {int(x[0]): x[1] for x in data_list1}
+    docid_json_dict = {int(x[0]): x[-1] for x in data_list2}
+    docid_tenderee_dict = {int(x[0]): x[-1] for x in data_list3}
+
+    all_data = []
+    # instruction = '根据上述招投标行业公告,进行要素提取,输出psv格式:\n'
+
+    empty_char = '-'
+    instruction = f"""
+你是招投标要素抽取专家。
+请严格按下面PSV格式输出,禁止修改表头,空字段置为{empty_char},字段之间用|分隔,首尾不加|。
+
+项目名称|招标人名称|代理人名称
+
+招标人联系人|招标人联系人电话
+
+标段名称|标段号|中标人名称|中标金额|中标金额单位|标段预算|标段预算单位
+
+产品名称|品牌|规格型号|数量|单价|总价|品目名称|品目编号
+
+请抽取以上内容并严格按上述4段PSV输出: 
+"""
+
+    for line in data_list1:
+        docid = int(line[0])
+
+        html = docid_html_dict.get(docid)
+        extract_json = docid_json_dict.get(docid)
+        labeled_tenderee = docid_tenderee_dict.get(docid)
+
+        if len(labeled_tenderee) <= 1:
+            labeled_tenderee = ''
+
+        text = html2text_with_table_html(html)
+        try:
+            extract_json = json.loads(extract_json)
+            # 用人工标注的替换json里的tenderee
+            prem = extract_json.get('prem')
+            project_dict = {
+                'code': "",
+                'name': "",
+                'roleList': [
+                    {
+                        'address': "",
+                        'linklist': [],
+                        'role_money': {},
+                        'role_name': 'tenderee',
+                        'role_text': labeled_tenderee,
+                    }
+                ],
+                'tendereeMoney': 0,
+                'tendereeMoneyUnit': "",
+            }
+            if not prem:
+                prem = {'Project': project_dict}
+            else:
+                # 每个包都加上tenderee
+                for k, d in prem.items():
+                    role_list = d.get('roleList')
+                    role_list += [
+                        {
+                            'address': "",
+                            'linklist': [],
+                            'role_money': {},
+                            'role_name': 'tenderee',
+                            'role_text': labeled_tenderee,
+                        }
+                    ]
+                    d['roleList'] = role_list
+                    prem[k] = d
+            extract_json['prem'] = prem
+
+            answer = extract_json_to_psv(extract_json, empty_char=empty_char)
+            if answer is None:
+                print('answer is None')
+                continue
+        except:
+            traceback.print_exc()
+            continue
+
+        train_data = {
+            "instruction": instruction,
+            "input": text,
+            "output": answer,
+        }
+        all_data.append(json.dumps(train_data, ensure_ascii=False))
+
+    # 生成
+    train_ratio = 0.9
+    dev_ratio = 0.1
+
+    random.shuffle(all_data)
+    total = len(all_data)
+    train_num = int(total * train_ratio)
+    dev_num = int(total * dev_ratio)
+
+    # 拆分
+    train_lines = all_data[:train_num]
+    dev_lines = all_data[train_num:train_num+dev_num]
+    test_lines = all_data[train_num+dev_num:]
+
+    print('len(train_lines)', len(train_lines))
+    print('len(dev_lines)', len(dev_lines))
+
+    # 保存
+    train_path = "data4/train_data.jsonl"
+    dev_path = "data4/dev_data.jsonl"
+    test_path = "data4/test_data.jsonl"
+    with open(train_path, 'w', encoding='utf-8') as f:
+        f.write("\n".join(train_lines))
+    with open(dev_path, 'w', encoding='utf-8') as f:
+        f.write("\n".join(dev_lines))
+    with open(test_path, 'w', encoding='utf-8') as f:
+        f.write("\n".join(test_lines))
+
+
+def xlsx_data_to_jsonl_3_prefix():
+    df1 = pd.read_csv(r'D:\BIDI_DOC\比地_文档\export_ai_260327_2.csv')
+    df2 = pd.read_csv(r'C:\Users\Administrator\Downloads\document_tmp_has_ai_no_attachment_260327_limit.csv')
+    data_list1 = df1.astype(object).where(pd.notnull(df1), "").values.tolist()
+    data_list2 = df2.astype(object).where(pd.notnull(df2), "").values.tolist()
+    docid_html_dict = {int(x[0]): x[1] for x in data_list1}
+    docid_json_dict = {int(x[0]): x[-1] for x in data_list2}
+
+    all_data = []
+    # instruction = '根据上述招投标行业公告,进行要素提取,输出psv格式:\n'
+
+    empty_char = '-'
+    instruction = f"""
+你是招投标要素抽取专家。
+请严格按下面PSV格式输出,禁止修改表头,空字段置为{empty_char},字段之间用|分隔,首尾不加|。
+
+项目名称|招标人名称|代理人名称
+
+招标人联系人|招标人联系人电话
+
+标段名称|标段号|中标人名称|中标金额|中标金额单位|标段预算|标段预算单位
+
+产品名称|品牌|规格型号|数量|单价|总价|品目名称|品目编号
+
+请抽取以上内容并严格按上述4段PSV输出:
+"""
+
+    instruction2 = f"""
+你是招投标要素抽取专家。
+请严格按下面PSV格式输出,禁止修改表头,空字段置为{empty_char},字段之间用|分隔,首尾不加|。
+
+招标人|招标人表达
+
+请抽取以上内容并严格按上述1段PSV输出: 
+"""
+
+    instruction3 = f"""
+你是招投标要素抽取专家。
+请严格按下面PSV格式输出,禁止修改表头,空字段置为{empty_char},字段之间用|分隔,首尾不加|。
+
+产品名称|品牌|规格型号|数量|单价|总价|品目名称|品目编号
+
+请抽取以上内容并严格按上述1段PSV输出: 
+"""
+
+    for line in data_list1:
+        docid = int(line[0])
+
+        html = docid_html_dict.get(docid)
+        extract_json = docid_json_dict.get(docid)
+
+        text = html2text_with_table_html(html)
+        try:
+            answer = extract_json_to_psv_prefix(json.loads(extract_json), text,
+                                                empty_char=empty_char)
+            if answer is None:
+                continue
+        except:
+            continue
+
+        print('answer0', answer)
+        train_data = {
+            "instruction": instruction,
+            "input": text,
+            "output": answer,
+        }
+        all_data.append(json.dumps(train_data, ensure_ascii=False))
+
+        answer = extract_json_to_psv_prefix(json.loads(extract_json), text,
+                                            empty_char=empty_char, prefix='[仅招标人]')
+        print('answer1', answer)
+        if answer is None:
+            continue
+        train_data = {
+            "instruction": instruction2,
+            "input": text,
+            "output": answer,
+        }
+        all_data.append(json.dumps(train_data, ensure_ascii=False))
+
+        answer = extract_json_to_psv_prefix(json.loads(extract_json), text,
+                                            empty_char=empty_char, prefix='[仅产品]')
+        print('answer2', answer)
+        if answer is None:
+            continue
+        train_data = {
+            "instruction": instruction3,
+            "input": text,
+            "output": answer,
+        }
+        all_data.append(json.dumps(train_data, ensure_ascii=False))
+
+    # 生成
+    train_ratio = 0.9
+    dev_ratio = 0.1
+
+    random.shuffle(all_data)
+    total = len(all_data)
+    train_num = int(total * train_ratio)
+    dev_num = int(total * dev_ratio)
+
+    # 拆分
+    train_lines = all_data[:train_num]
+    dev_lines = all_data[train_num:train_num+dev_num]
+    test_lines = all_data[train_num+dev_num:]
+
+    print('len(train_lines)', len(train_lines))
+    print('len(dev_lines)', len(dev_lines))
+
+    # 保存
+    # train_path = "data3_prefix/train_data.jsonl"
+    # dev_path = "data3_prefix/dev_data.jsonl"
+    # test_path = "data3_prefix/test_data.jsonl"
+    train_path = "data7_prefix/train_data.jsonl"
+    dev_path = "data7_prefix/dev_data.jsonl"
+    test_path = "data7_prefix/test_data.jsonl"
+    with open(train_path, 'w', encoding='utf-8') as f:
+        f.write("\n".join(train_lines))
+    with open(dev_path, 'w', encoding='utf-8') as f:
+        f.write("\n".join(dev_lines))
+    with open(test_path, 'w', encoding='utf-8') as f:
+        f.write("\n".join(test_lines))
+
+
+def entity_data_to_jsonl_prefix():
+    df1 = pd.read_excel(r'df_train.xlsx')
+    data_list1 = df1.astype(object).where(pd.notnull(df1), "").values.tolist()
+
+    empty_char = '-'
+    instruction = f"""
+你是招投标要素抽取专家。
+请严格按下面PSV格式输出,禁止修改表头,空字段置为{empty_char},字段之间用|分隔,首尾不加|。
+
+项目名称|招标人名称|代理人名称
+
+招标人联系人|招标人联系人电话
+
+标段名称|标段号|中标人名称|中标金额|中标金额单位|标段预算|标段预算单位
+
+产品名称|品牌|规格型号|数量|单价|总价|品目名称|品目编号
+
+请抽取以上内容并严格按上述4段PSV输出:
+"""
+
+    instruction2 = f"""
+你是招投标要素抽取专家。
+请严格按下面PSV格式输出,禁止修改表头,空字段置为{empty_char},字段之间用|分隔,首尾不加|。
+
+招标人|招标人表达
+
+请抽取以上内容并严格按上述1段PSV输出: 
+"""
+
+    all_data = []
+    max_cnt = 2000
+    cnt = 0
+    for line in data_list1:
+        center = line[1]
+        docid = line[2]
+        label = line[4]
+        left = line[5]
+        right = line[8]
+
+        if label != '招标人':
+            continue
+
+        if cnt >= max_cnt:
+            break
+
+        text = left + center + right
+
+        answer = entity_to_psv_prefix(text, center, empty_char=empty_char, prefix='[仅招标人]')
+        train_data = {
+            "instruction": instruction2,
+            "input": text,
+            "output": answer,
+        }
+        all_data.append(json.dumps(train_data, ensure_ascii=False))
+        cnt += 1
+
+    # 生成
+    train_ratio = 0.9
+    dev_ratio = 0.1
+
+    random.shuffle(all_data)
+    total = len(all_data)
+    train_num = int(total * train_ratio)
+    dev_num = int(total * dev_ratio)
+
+    # 拆分
+    train_lines = all_data[:train_num]
+    dev_lines = all_data[train_num:train_num+dev_num]
+    test_lines = all_data[train_num+dev_num:]
+
+    print('len(train_lines)', len(train_lines))
+    print('len(dev_lines)', len(dev_lines))
+
+    # 保存
+    train_path = "data5_prefix/train_data.jsonl"
+    dev_path = "data5_prefix/dev_data.jsonl"
+    test_path = "data5_prefix/test_data.jsonl"
+    with open(train_path, 'w', encoding='utf-8') as f:
+        f.write("\n".join(train_lines))
+    with open(dev_path, 'w', encoding='utf-8') as f:
+        f.write("\n".join(dev_lines))
+    with open(test_path, 'w', encoding='utf-8') as f:
+        f.write("\n".join(test_lines))
+
+
+def augment_jsonl_data():
+
+    tags = ['[仅招标人]', '[全字段]']
+
+    train_path = './data6_prefix/train_data.jsonl'
+    output_path = './data6_prefix_aug/train_data.jsonl'
+    data_dict_list = []
+    with open(train_path, 'r', encoding='utf-8') as f:
+        for line in f:
+            line = json.loads(line.strip())
+            # 构造Qwen的输入格式(Chat版格式)
+            prompt = f"<|im_start|>user\n{line['input']}\n{line['instruction']}<|im_end|>\n<|im_start|>assistant\n{line['output']}<|im_end|>"
+            input_data = line['input']
+            output_data = line['output']
+            # print('output_data', output_data)
+            data_dict_list.append(line)
+
+    # project_name, tenderee, agency 位置打乱
+    new_data_dict_list = []
+    for data_dict in data_dict_list:
+
+        # 50% 打乱
+        if random.choice([0, 1]):
+            new_data_dict_list.append(data_dict)
+            continue
+
+        text = data_dict['input']
+        output = data_dict['output']
+
+        now_tag = None
+        for tag in tags:
+            if tag in output:
+                output = re.sub(tag, '', str(output))
+                now_tag = tag
+                break
+
+        first_table = output.split('\n')[1]
+
+        if now_tag == '[仅招标人]':
+            tenderee, _ = first_table.split('|')[:2]
+            project_name = ''
+            agency = ''
+        else:
+            project_name, tenderee, agency = first_table.split('|')[:3]
+
+        if len(tenderee) <= 1:
+            continue
+
+        # sen_list = re.split('[,。;?!]', text)
+        sen_list = re.findall('[^,。;?!\n]+[,。;?!\n]?', text)
+
+        tenderee_sen_list = []
+        agency_sen_list = []
+        project_name_sen_list = []
+        for sen in sen_list:
+            match = re.search(re.escape(tenderee), sen)
+            if match:
+                tenderee_sen_list.append(sen)
+
+            if len(agency) > 1:
+                match = re.search(re.escape(agency), sen)
+                if match:
+                    agency_sen_list.append(sen)
+
+            if len(project_name) > 1:
+                match = re.search(re.escape(project_name), sen)
+                if match:
+                    project_name_sen_list.append(sen)
+
+        for sen in project_name_sen_list:
+            if sen in tenderee_sen_list:
+                tenderee_sen_list.remove(sen)
+
+        if len(tenderee_sen_list) == 0:
+            continue
+
+        if len(tenderee_sen_list) >= 2:
+            print('tenderee_sen_list', tenderee_sen_list)
+            continue
+
+        for sen in tenderee_sen_list + agency_sen_list + project_name_sen_list:
+            if sen in sen_list:
+                sen_list.remove(sen)
+
+        print('len(sen_list)', len(sen_list))
+        if len(sen_list) <= 1:
+            print('len(sen_list) <= 1', sen_list)
+            continue
+
+        random_index = random.randint(1, len(sen_list)-1)
+        tenderee_sen = tenderee_sen_list[0]
+
+        if '<' in tenderee_sen:
+            continue
+
+        print('tenderee_sen', tenderee_sen, tenderee)
+
+        sen_list = sen_list[:random_index] + [tenderee_sen] + sen_list[random_index:]
+
+        if agency_sen_list:
+            random_index = random.randint(1, len(sen_list)-1)
+            agency_sen = agency_sen_list[0]
+            print('agency_sen', agency_sen)
+            sen_list = sen_list[:random_index] + [agency_sen] + sen_list[random_index:]
+
+        if project_name_sen_list:
+            random_index = random.randint(1, len(sen_list)-1)
+            project_name_sen = project_name_sen_list[0]
+            print('project_name_sen', project_name_sen)
+            sen_list = sen_list[:random_index] + [project_name_sen] + sen_list[random_index:]
+
+        new_text = ''.join(sen_list)
+        data_dict['input'] = new_text
+        new_data_dict_list.append(data_dict)
+
+    print('len(new_data_dict_list)', len(new_data_dict_list))
+
+    _str = '\n'.join([json.dumps(x, ensure_ascii=False) for x in new_data_dict_list])
+
+    with open(output_path, 'w', encoding='utf-8') as f:
+        f.write(_str)
+    print('finish to', output_path)
+
+
+def table_list_to_psv(table_list, empty_char, table_type=None):
+    final_str = ''
+    show_flag = 0
+    for table_cols, table_values in table_list:
+        str1 = '|'.join(table_cols) + '\n'
+
+        continue_flag = 0
+
+        if table_values:
+            str2 = ''
+            if len(table_values) >= 2:
+                # print('table_values', table_values)
+                show_flag = 1
+            for line in table_values:
+                if '|' in str(line):
+                    continue_flag = 1
+                    break
+                str2 += '|'.join([str(x) if str(x) != '' else empty_char for x in line]) + '\n'
+            if not str2:
+                str2 = '|'.join([empty_char for x in table_cols]) + '\n'
+        else:
+            str2 = '|'.join([empty_char for x in table_cols]) + '\n'
+
+        if continue_flag:
+            return None
+
+        # 判断表头和内容竖线是否相同
+        # for ss2 in str2.split('\n'):
+        #     if len(ss2) == 0:
+        #         continue
+        #     if len(re.findall("\|", str1)) != len(re.findall("\|", ss2)):
+        #         print('--- str1', str1)
+        #         print('--- str2', ss2)
+        #         return None
+
+        if len(re.findall("\|", str2)) % len(re.findall("\|", str1)) != 0:
+            print('--- str1', str1)
+            print('--- str2', str2)
+            return None
+
+        final_str += str1
+        final_str += str2
+        final_str += '\n'
+
+    final_str = re.sub('未提及', f'{empty_char}', final_str)
+
+    delete_value_list = ['None', '无', '无品牌', '无型号', '0', '0.0', '未提及']
+    for v in delete_value_list:
+        final_str = re.sub(f'\|{v}\|', f'|{empty_char}|', final_str)
+        final_str = re.sub(f'\|{v}\n', f'|{empty_char}\n', final_str)
+        final_str = re.sub(f'\n{v}\|', f'\n{empty_char}|', final_str)
+    return final_str
+
+
+def saimofei_to_psv_prefix(data_list, text, prefix, empty_char='-'):
+    project_name = data_list[0].get('doctitle')
+    tenderee = data_list[0].get('tenderee')
+    agency = data_list[0].get('agency')
+
+    tenderee_contact_list = []
+    win_tenderer_info_list = []
+    product_list = []
+    for d in data_list:
+        # tenderee_contact_list
+        tenderee_contact = d.get('tenderee_contact')
+        if '/' in tenderee_contact:
+            tenderee_person, tenderee_phone = tenderee_contact.split('/')
+        else:
+            tenderee_phone = tenderee_contact
+            tenderee_person = ''
+        tenderee_contact_list.append([tenderee_person, tenderee_phone])
+
+        # win_tenderer_info_list
+        win_tenderer = d.get('tenderee_contact')
+        project_code = d.get('project_code')
+        budget = d.get('budget')
+        win_money = d.get('win_money')
+        budget = str(getUnifyMoney(budget))
+        win_money = str(getUnifyMoney(win_money))
+        win_tenderer_info = [
+            '-', project_code, win_tenderer, win_money,
+            '元', budget, '元',
+        ]
+        win_tenderer_info_list.append(win_tenderer_info)
+
+        # product_list
+        product_name = d.get('product_name')
+        brand = d.get('brand')
+        specs = d.get('specs')
+        product_cnt = d.get('product_cnt')
+        unit_price = d.get('unit_price')
+        total_price = d.get('total_price')
+        product_list.append([
+            product_name, brand, specs, product_cnt,
+            unit_price, total_price, '-', '-'
+        ])
+
+    tenderee_contact_list = list(set([json.dumps(x) for x in tenderee_contact_list]))
+    tenderee_contact_list = [json.loads(x) for x in tenderee_contact_list]
+    win_tenderer_info_list = list(set([json.dumps(x) for x in win_tenderer_info_list]))
+    win_tenderer_info_list = [json.loads(x) for x in win_tenderer_info_list]
+    product_list = list(set([json.dumps(x) for x in product_list]))
+    product_list = [json.loads(x) for x in product_list]
+
+    if prefix == '[全字段]':
+        table_list = []
+        # table 1
+        table_cols = ['项目名称', '招标人名称', '代理人名称']
+        table_values = [[project_name, tenderee, agency]]
+        table_list.append([table_cols, table_values])
+
+        # table 2
+        table_cols = ['招标人联系人', '招标人联系人电话']
+        # print('tenderee_contact_list', tenderee_contact_list)
+        table_values = tenderee_contact_list if tenderee_contact_list else []
+        temp_list = []
+        for v in table_values:
+            if (v[0] not in [None, '', '-'] and v[0] in text) \
+                    or (v[1] not in [None, '', '-'] and v[1] in text):
+                temp_list.append(v)
+        table_values = temp_list
+        table_list.append([table_cols, table_values])
+
+        # table 3
+        table_cols = ['标段名称', '标段号', '中标人名称', '中标金额', '中标金额单位', '标段预算', '标段预算单位']
+        table_values = win_tenderer_info_list if win_tenderer_info_list else []
+        temp_list = []
+        for v in table_values:
+            if (v[0] not in [None, '', '-'] and v[0] in text) \
+                    or (v[2] not in [None, '', '-'] and v[2] in text) \
+                    or (v[1] not in [None, '', '-'] and v[1] in text):
+                temp_list.append(v)
+        table_values = temp_list
+        table_list.append([table_cols, table_values])
+
+        # table 4
+        table_cols = ['产品名称', '品牌', '规格型号', '数量', '单价', '总价', '品目名称', '品目编号']
+        table_values = product_list if product_list else []
+        temp_list = []
+        for v in table_values:
+            if v[0] not in [None, '', '-'] and v[0] in text:
+                temp_list.append(v)
+        table_values = temp_list
+
+        # # 产品中数值类型 重复3次
+        # for v in table_values:
+        #     for col_i in [3, 4, 5]:
+        #         try:
+        #             col_v = float(v[col_i])
+        #             if col_v > 0:
+        #                 v[col_i] = ','.join([v[col_i], v[col_i], v[col_i]])
+        #         except:
+        #             pass
+
+        table_list.append([table_cols, table_values])
+
+        final_str = table_list_to_psv(table_list, empty_char)
+        if not final_str:
+            return final_str
+        final_str = prefix + final_str
+        return final_str
+
+    elif prefix == '[仅招标人]':
+        if not tenderee:
+            return None
+
+        sen_list = re.findall('[^,。;?!\n]+[,。;?!\n]?', text)
+        tenderee_sen_list = []
+        for sen in sen_list:
+            match = re.search(re.escape(tenderee), sen)
+            if match:
+                tenderee_sen_list.append(sen)
+        if tenderee_sen_list:
+            tenderee_sen_list.sort(key=lambda x: len(x))
+            tenderee_line = tenderee_sen_list[0]
+        else:
+            tenderee_line = empty_char
+
+        table_list = []
+        table_cols = ['招标人', '招标人表达']
+        table_values = [[tenderee, tenderee_line]]
+        table_list.append([table_cols, table_values])
+
+        final_str = table_list_to_psv(table_list, empty_char)
+        if not final_str:
+            return final_str
+        final_str = prefix + final_str
+        return final_str
+
+    elif prefix == '[仅产品]':
+        table_cols = ['产品名称', '品牌', '规格型号', '数量', '单价', '总价', '品目名称', '品目编号']
+        table_values = product_list if product_list else []
+
+        # 判断截取后产品是否还在其中
+        # if len(text) >= 10000:
+        #     sub_text = text[:10000]
+        temp_list = []
+        for v in table_values:
+            if v[0] not in [None, '', '-'] and v[0] in text:
+                temp_list.append(v)
+        table_values = temp_list
+
+        # # 产品中数值类型 重复3次
+        # for v in table_values:
+        #     for col_i in [3, 4, 5]:
+        #         try:
+        #             col_v = float(v[col_i])
+        #             if col_v > 0:
+        #                 v[col_i] = ','.join([v[col_i], v[col_i], v[col_i]])
+        #         except:
+        #             pass
+
+        table_list = []
+        table_list.append([table_cols, table_values])
+        final_str = table_list_to_psv(table_list, empty_char)
+        if not final_str:
+            return final_str
+        final_str = prefix + final_str
+        return final_str
+
+
+def saimofei_data_to_jsonl_data():
+    df = pd.read_excel(r'C:\Users\Administrator\Downloads\赛默飞-样例数据.xlsx', header=1)
+    df1 = pd.read_csv(r'D:\BIDI_DOC\比地_文档\export_ai_260417_saimofei_html.csv')
+    head_list = list(df.columns)
+    data_list = df.astype(object).where(pd.notnull(df), "").values.tolist()
+    data_list1 = df1.astype(object).where(pd.notnull(df1), "").values.tolist()
+
+    docid_html_dict = {int(x[0]): x[1] for x in data_list1}
+
+    docid_data_dict = {}
+    for data in data_list:
+        docid = data[head_list.index('公告ID')]
+        doctitle = data[head_list.index('公告名称')]
+        budget = data[head_list.index('预算金额')]
+        win_money = data[head_list.index('成交金额')]
+        tenderee = data[head_list.index('招标单位')]
+        tenderee_contact = data[head_list.index('招标单位联系人')]
+        agency = data[head_list.index('代理机构')]
+        win_tenderer = data[head_list.index('中标单位')]
+        product_name = data[head_list.index('产品名称')]
+        brand = data[head_list.index('品牌名称')]
+        specs = data[head_list.index('型号')]
+        product_cnt = data[head_list.index('数量')]
+        unit_price = data[head_list.index('单价(元)')]
+        total_price = data[head_list.index('总价(元)')]
+        project_code = data[head_list.index('项目编号')]
+
+        new_data = {
+            'doctitle': doctitle,
+            'budget': budget,
+            'win_money': win_money,
+            'tenderee': tenderee,
+            'tenderee_contact': tenderee_contact,
+            'agency': agency,
+            'win_tenderer': win_tenderer,
+            'product_name': product_name,
+            'brand': brand,
+            'specs': specs,
+            'product_cnt': product_cnt,
+            'unit_price': unit_price,
+            'total_price': total_price,
+            'project_code': project_code,
+        }
+
+        if docid in docid_data_dict:
+            docid_data_dict[int(docid)] += [new_data]
+        else:
+            docid_data_dict[int(docid)] = [new_data]
+
+    all_data = []
+    empty_char = '-'
+    instruction = f"""
+你是招投标要素抽取专家。
+请严格按下面PSV格式输出,禁止修改表头,空字段置为{empty_char},字段之间用|分隔,首尾不加|。
+
+项目名称|招标人名称|代理人名称
+
+招标人联系人|招标人联系人电话
+
+标段名称|标段号|中标人名称|中标金额|中标金额单位|标段预算|标段预算单位
+
+产品名称|品牌|规格型号|数量|单价|总价|品目名称|品目编号
+
+请抽取以上内容并严格按上述4段PSV输出:
+"""
+
+    instruction2 = f"""
+你是招投标要素抽取专家。
+请严格按下面PSV格式输出,禁止修改表头,空字段置为{empty_char},字段之间用|分隔,首尾不加|。
+
+招标人|招标人表达
+
+请抽取以上内容并严格按上述1段PSV输出: 
+"""
+
+    instruction3 = f"""
+你是招投标要素抽取专家。
+请严格按下面PSV格式输出,禁止修改表头,空字段置为{empty_char},字段之间用|分隔,首尾不加|。
+
+产品名称|品牌|规格型号|数量|单价|总价|品目名称|品目编号
+
+请抽取以上内容并严格按上述1段PSV输出: 
+"""
+
+    for docid, data_list in docid_data_dict.items():
+        html = docid_html_dict.get(int(docid))
+        text = html2text_with_table_html(html)
+
+        answer = saimofei_to_psv_prefix(data_list, text, prefix='[全字段]', empty_char=empty_char)
+        print('answer1', answer)
+        if not answer:
+            continue
+        train_data = {
+            "instruction": instruction,
+            "input": text,
+            "output": answer,
+        }
+        all_data.append(json.dumps(train_data, ensure_ascii=False))
+
+        answer = saimofei_to_psv_prefix(data_list, text, prefix='[仅招标人]', empty_char=empty_char)
+        print('answer2', answer)
+        if not answer:
+            continue
+        train_data = {
+            "instruction": instruction2,
+            "input": text,
+            "output": answer,
+        }
+        all_data.append(json.dumps(train_data, ensure_ascii=False))
+
+        answer = saimofei_to_psv_prefix(data_list, text, prefix='[仅产品]', empty_char=empty_char)
+        print('answer3', answer)
+        if not answer:
+            continue
+        train_data = {
+            "instruction": instruction3,
+            "input": text,
+            "output": answer,
+        }
+        all_data.append(json.dumps(train_data, ensure_ascii=False))
+
+    # 生成
+    train_ratio = 0.9
+    dev_ratio = 0.1
+
+    random.shuffle(all_data)
+    total = len(all_data)
+    train_num = int(total * train_ratio)
+    dev_num = int(total * dev_ratio)
+
+    # 拆分
+    train_lines = all_data[:train_num]
+    dev_lines = all_data[train_num:train_num+dev_num]
+    test_lines = all_data[train_num+dev_num:]
+
+    print('len(train_lines)', len(train_lines))
+    print('len(dev_lines)', len(dev_lines))
+
+    # 保存
+    train_path = "data6_prefix/train_data.jsonl"
+    dev_path = "data6_prefix/dev_data.jsonl"
+    test_path = "data6_prefix/test_data.jsonl"
+    with open(train_path, 'w', encoding='utf-8') as f:
+        f.write("\n".join(train_lines))
+    with open(dev_path, 'w', encoding='utf-8') as f:
+        f.write("\n".join(dev_lines))
+    with open(test_path, 'w', encoding='utf-8') as f:
+        f.write("\n".join(test_lines))
+
+
+if __name__ == '__main__':
+    # filter_data_docid()
+
+    # xlsx_data_to_jsonl()
+    # xlsx_data_to_jsonl_2()
+    # xlsx_data_to_jsonl_3()
+    # xlsx_data_to_jsonl_4_prefix()
+    # xlsx_data_to_jsonl_5()
+    xlsx_data_to_jsonl_3_prefix()
+    # entity_data_to_jsonl_prefix()
+
+    # saimofei_data_to_jsonl_data()
+
+    # augment_jsonl_data()

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 458 - 0
qwen_lora/infer_files.py


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 161 - 0
qwen_lora/infer_llama.py


+ 121 - 0
qwen_lora/infer_ollama.py

@@ -0,0 +1,121 @@
+import base64
+import random
+import re
+import traceback
+
+import pandas as pd
+import requests
+from bs4 import BeautifulSoup
+from openai import OpenAI
+import time
+
+# client = OpenAI(base_url="http://192.168.2.103:11434/v1", api_key="ollama")
+#
+# instruction = '提取以上招投标文档的关键信息,只输出有值的,其中中标人等放在多标段信息中形成数组,' \
+#               '产品参数等放在产品信息中形成数组' \
+#               '金额均以元为单位,时间格式为YYYY-MM-DD HH:MM:SS,无多余内容' \
+#               '直接得到要素提取Json:'
+#
+# answer_prefix = '{"项目名称":'
+#
+# _text = "树村220千伏变电站110千伏送出工程-拆改工程(设计)中标候选人公示 招标项目名称: 树村220千伏变电站110千伏送出工程-拆改工程(设计) 招标编号: 91110108777085234D 招标项目编号: Z1101000311004312001 所属行业: 其他 所属地区: 北京市-海淀区 开始时间: 2026-03-06 结束时间: 2026-03-10 招标单位: 北京海融达投资建设有限公司 招标代理: 天行健项目管理咨询(北京)有限公司 发布时间: 2026-03-06 17:17:12.0 公示内容 公告文件.pdf"
+#
+# prompt = f"<|im_start|>user\n{_text}\n{instruction}<|im_end|>\n<|im_start|>assistant\n{answer_prefix}"
+#
+#
+# start_time = time.time()
+# response = client.chat.completions.create(
+#     model="bidding-qwen-0.8B-lora-16K",
+#     messages=[{"role": "user", "content": prompt}],
+#     temperature=0,
+#     stop=["<|im_end|>", "<|endoftext|>", "###"],
+#     max_tokens=4096,
+# )
+# end_time = time.time()
+#
+# answer = response.choices[0].message.content
+# answer = answer_prefix + answer
+#
+# # 获取指标
+# usage = response.usage
+# prompt_tokens = usage.prompt_tokens
+# completion_tokens = usage.completion_tokens
+# total_duration = end_time - start_time
+# tps = completion_tokens / total_duration if total_duration > 0 else 0
+#
+# print(f"回答: {answer}")
+# print("-" * 30)
+# print(f"指标统计:")
+# print(f"  - 输入 Tokens: {prompt_tokens}")
+# print(f"  - 输出 Tokens: {completion_tokens}")
+# print(f"  - 总耗时: {total_duration:.2f} s")
+# print(f"  - 推理速度: {tps:.2f} tokens/s")
+
+url = "http://192.168.2.103:11434/api/generate"
+url2 = "http://192.168.2.103:11435/api/generate"
+url_docker = "http://192.168.2.103:11436/api/generate"
+url_docker_chat = "http://192.168.2.103:11436/api/chat"
+
+
+def infer_ollama_api(prompt, answer_prefix, model_name=None, temperature=0.05):
+    # 构造 Prompt,直接把前缀放在最后
+    # instruction = '提取以上招投标文档的关键信息,只输出有值的,其中中标人等放在多标段信息中形成数组,' \
+    #               '产品参数等放在产品信息中形成数组' \
+    #               '金额均以元为单位,时间格式为YYYY-MM-DD HH:MM:SS,无多余内容' \
+    #               '直接得到要素提取Json:'
+    #
+    # answer_prefix = '{"项目名称":'
+    #
+    # _text = "树村220千伏变电站110千伏送出工程-拆改工程(设计)中标候选人公示 招标项目名称: 树村220千伏变电站110千伏送出工程-拆改工程(设计) 招标编号: 91110108777085234D 招标项目编号: Z1101000311004312001 所属行业: 其他 所属地区: 北京市-海淀区 开始时间: 2026-03-06 结束时间: 2026-03-10 招标单位: 北京海融达投资建设有限公司 招标代理: 天行健项目管理咨询(北京)有限公司 发布时间: 2026-03-06 17:17:12.0 公示内容 公告文件.pdf"
+    #
+    # prompt = f"<|im_start|>user\n{_text}\n{instruction}<|im_end|>\n<|im_start|>assistant\n{answer_prefix}"
+    #
+
+    # if random.choice([0, 1]):
+    #     model_name = "bidding-qwen-0.8B-lora-16k:latest"
+    # else:
+    #     model_name = "bidding-qwen-0.8B-lora-16k-2:latest"
+    # print('infer_ollama_api random choice model_name', model_name)
+
+    # if random.choice([0, 1]):
+    #     now_url = url
+    # else:
+    #     now_url = url2
+    # print('infer_ollama_api random choice now_url', now_url)
+
+    now_url = url_docker
+
+    if model_name is None:
+        model_name = "bidding-qwen-0.8B-lora-16k:latest"
+    # model_name = 'deepseek-r1:1.5b'
+    print('infer_ollama_api', now_url, model_name)
+
+    payload = {
+        "model": model_name,
+        # "model": "bidding-qwen-2B-lora-16k:latest",
+        # "model": "qwen3.5:0.8b",
+        "prompt": prompt,
+        "stream": False,
+        "raw": True,
+        "options": {
+            "num_ctx": int(1024*16),
+            "temperature": temperature,
+            "num_predict": 4096,
+            "repeat_penalty": 1.18,
+            "repeat_last_n": -1,
+            "stop": ["<|im_end|>", "<|endoftext|>"],
+            "seed": 42,          # 固定随机种子
+            "top_k": 50,          # 只选概率最高的一个 Token(贪婪搜索)
+            "top_p": 0.99,
+        }
+    }
+
+    response = requests.post(now_url, json=payload)
+    result = response.json()
+
+    # 核心:手动把你的前缀和模型生成的后续内容拼起来
+    final_content = answer_prefix + result["response"]
+    # print(final_content)
+    return final_content
+
+

+ 121 - 0
qwen_lora/load_data.py

@@ -0,0 +1,121 @@
+import json
+from datasets import Dataset
+
+
+def load_bid_data(train_path_list, dev_path_list):
+    """加载招投标数据"""
+    # 加载训练集
+    train_data = []
+    for train_path in train_path_list:
+        with open(train_path, 'r', encoding='utf-8') as f:
+            for line in f:
+                line = json.loads(line.strip())
+                # 构造Qwen的输入格式(Chat版格式)
+                prompt = f"<|im_start|>user\n{line['input']}\n{line['instruction']}<|im_end|>\n<|im_start|>assistant\n{line['output']}<|im_end|>"
+                train_data.append({"text": prompt})
+
+    # 加载验证集
+    dev_data = []
+    for dev_path in dev_path_list:
+        with open(dev_path, 'r', encoding='utf-8') as f:
+            for line in f:
+                line = json.loads(line.strip())
+                prompt = f"<|im_start|>user\n{line['input']}\n{line['instruction']}<|im_end|>\n<|im_start|>assistant\n{line['output']}<|im_end|>"
+                dev_data.append({"text": prompt})
+
+    # dev_data = dev_data[:10]
+
+    print('len(train_data)', len(train_data))
+    print('len(dev_data)', len(dev_data))
+
+    # 转为Dataset格式
+    train_dataset = Dataset.from_list(train_data)
+    dev_dataset = Dataset.from_list(dev_data)
+    return train_dataset, dev_dataset
+
+
+def load_bid_data_dpo(train_path_list, dev_path_list):
+    """加载招投标数据"""
+    # 加载训练集
+    train_data = []
+    for train_path in train_path_list:
+        with open(train_path, 'r', encoding='utf-8') as f:
+            for line in f:
+                line = json.loads(line.strip())
+                train_data.append(
+                    {
+                        "text_prompt": line['prompt'], "chosen": line['chosen'],
+                        "rejected": line['rejected'],
+                    }
+                )
+
+    # 加载验证集
+    dev_data = []
+    for dev_path in dev_path_list:
+        with open(dev_path, 'r', encoding='utf-8') as f:
+            for line in f:
+                line = json.loads(line.strip())
+                dev_data.append(
+                    {
+                        "text_prompt": line['prompt'], "chosen": line['chosen'],
+                        "rejected": line['rejected'],
+                    }
+                )
+
+    # dev_data = dev_data[:10]
+
+    print('len(train_data)', len(train_data))
+    print('len(dev_data)', len(dev_data))
+
+    # 转为Dataset格式
+    train_dataset = Dataset.from_list(train_data)
+    dev_dataset = Dataset.from_list(dev_data)
+
+    # # 核心:添加这一列,内容全是 None
+    # train_dataset = train_dataset.add_column("images", [None] * len(train_dataset))
+    # dev_dataset = dev_dataset.add_column("images", [None] * len(dev_dataset))
+    return train_dataset, dev_dataset
+
+
+def load_bid_data_kto(train_path_list, dev_path_list):
+    train_data = []
+    for train_path in train_path_list:
+        with open(train_path, 'r', encoding='utf-8') as f:
+            for line in f:
+                line = json.loads(line.strip())
+                prompt = line["prompt"]
+                chosen = line["chosen"]
+                rejected = line["rejected"]
+
+                # 👇 正确:拆成两条 KTO 样本
+                train_data.append({"prompt": prompt, "completion": chosen, "label": True})
+                train_data.append({"prompt": prompt, "completion": rejected, "label": False})
+
+    dev_data = []
+    for dev_path in dev_path_list:
+        with open(dev_path, 'r', encoding='utf-8') as f:
+            for line in f:
+                line = json.loads(line.strip())
+                prompt = line["prompt"]
+                chosen = line["chosen"]
+                rejected = line["rejected"]
+
+                dev_data.append({"prompt": prompt, "completion": chosen, "label": True})
+                dev_data.append({"prompt": prompt, "completion": rejected, "label": False})
+
+    print('len(train_data)', len(train_data))
+    print('len(dev_data)', len(dev_data))
+
+    train_dataset = Dataset.from_list(train_data)
+    dev_dataset = Dataset.from_list(dev_data)
+    return train_dataset, dev_dataset
+
+
+# 测试加载
+if __name__ == "__main__":
+    train_ds, dev_ds = load_bid_data("data/train_data.jsonl", "data/dev_data.jsonl")
+    print(f"训练集数量:{len(train_ds)}")
+    print(f"验证集数量:{len(dev_ds)}")
+
+    for ds in train_ds:
+        print(f"示例数据:{ds['text']}")

+ 34 - 0
qwen_lora/merge_model.py

@@ -0,0 +1,34 @@
+import os
+
+os.environ["CUDA_VISIBLE_DEVICES"] = ""
+from transformers import AutoModelForCausalLM, AutoTokenizer
+from peft import PeftModel
+import torch
+
+
+# 由于 LoRA 权重不能直接转 GGUF,你必须先将它与原模型合并。
+
+lora_path = "model/qwen-0.8b-tender-lora/checkpoint-430"
+save_path = "model/qwen-merged-model"
+
+# 请将此处替换为你上面 find 命令查出来的真实绝对路径
+base_model_path = "/home/user/.cache/huggingface/hub/models--Qwen--Qwen3.5-0.8B/snapshots/2fc06364715b967f1860aea9cf38778875588b17"
+
+print(f"正在尝试从本地路径加载模型: {base_model_path}")
+
+# 显式指定从本地加载
+base_model = AutoModelForCausalLM.from_pretrained(
+    base_model_path,
+    torch_dtype=torch.float32,
+    device_map={"": "cpu"},
+    local_files_only=True, # 强制不联网,路径不对会立刻报错
+    trust_remote_code=True
+)
+
+model = PeftModel.from_pretrained(base_model, lora_path)
+merged_model = model.merge_and_unload()
+
+merged_model.save_pretrained(save_path)
+tokenizer = AutoTokenizer.from_pretrained(base_model_path)
+tokenizer.save_pretrained(save_path)
+print("模型已成功合并并保存。")

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.