建议使用vGPU-48GB(北京网速快),32GB也可以

先安装ollama,参考这个

【AI基础】租用云GPU之autoDL部署大模型ollama+llama3_autodl ollama-CSDN博客

ollama run dengcao/Qwen3-32B:Q5_K_M

新建Python文件excel_c.py,简单任务单条0.5秒左右

# -*- coding: utf-8 -*-
import argparse
import pandas as pd
import os
import sys
import time
import ollama
from ollama import ResponseError
from requests.exceptions import ConnectionError, Timeout
from tqdm import tqdm

def get_ai_response_ollama(client: ollama.Client, model: str, prompt: str, index: int) -> str:
    """
    使用Ollama客户端,发送单个请求并处理响应。
    (V2 - 已根据Qwen官方文档更新了模型参数)
    """
    print(f"\n--- [任务 {index}] ---")
    print(f"正在发送请求...", flush=True)
    start_time = time.time()
    
    try:
        messages = [{"role": "user", "content": prompt}]
        
        # *** 核心修改点: 使用 ollama.Client.chat ***
        chat_response = client.chat(
            model=model,
            messages=messages,
            # *** 参数优化: 根据Qwen官方文档为"非思考模式"设置参数 ***
            options={
                # --- 采样参数 (Sampling Parameters) ---
                'temperature': 0.7,         # 推荐值: 0.7
                'top_p': 0.8,               # 推荐值: 0.8
                'top_k': 20,                # 推荐值: 20
                'presence_penalty': 1.5,    # 推荐值: 1.5,用于抑制重复
                
                # --- 其他可用参数 (根据Ollama文档,min_p可能不直接支持,但以上是最关键的) ---
                # 'min_p': 0,               # Ollama的options可能不支持此参数,但影响较小
                
                # --- 输出长度 (Adequate Output Length) ---
                # 您的任务是精简输出,所以不需要超长上下文。
                # 如果是复杂推理任务,可以取消注释并设置一个较大的值。
                'num_ctx':32768,         # 对应 max_tokens 或上下文窗口
            }
        )
        
        duration = time.time() - start_time
        print(f"响应成功!耗时: {duration:.2f}秒。", flush=True)
        
        response_content = chat_response['message']['content'].strip()
        print(f"AI 响应内容: {response_content}", flush=True)
        
        return response_content
        
    except Timeout:
        error_msg = f"请求超时({client._timeout}秒)。服务器可能无响应或处理过慢。"
        print(f"[任务 {index} 错误] {error_msg}", file=sys.stderr, flush=True)
        return f"ERROR: {error_msg}"
    except ConnectionError:
        print(f"[任务 {index} 错误] {error_msg}", file=sys.stderr, flush=True)
        return f"ERROR: {error_msg}"
    except ResponseError as e:
        if e.status_code == 404:
            error_msg = f"模型未找到: '{model}'。请确认模型已下载且名称正确。"
        else:
            error_msg = f"API状态错误: status_code={e.status_code}, error={e.error}"
        print(f"[任务 {index} 错误] {error_msg}", file=sys.stderr, flush=True)
        return f"ERROR: {error_msg}"
    except Exception as e:
        error_msg = f"处理请求时发生未知错误: {type(e).__name__} - {e}"
        print(f"[任务 {index} 错误] {error_msg}", file=sys.stderr, flush=True)
        return f"ERROR: {error_msg}"

def process_excel_file(
    client: ollama.Client,
    file_path: str,
    column_name: str,
    prompt_template: str,
    output_file: str,
    model: str
):
    """
    读取Excel文件,使用串行请求处理指定列,并将结果保存到新文件。
    (此函数逻辑无需修改)
    """
    try:
        print(f"[信息] 正在读取文件: {file_path}")
        df = pd.read_excel(file_path)
        if column_name not in df.columns:
            print(f"[错误] 列 '{column_name}' 在文件中未找到。", file=sys.stderr)
            sys.exit(1)
        unique_inputs = df[column_name].dropna().unique().tolist()
        if not unique_inputs:
            print(f"[信息] 在列 '{column_name}' 中没有找到可处理的数据。", file=sys.stderr)
            sys.exit(0)
    except FileNotFoundError:
        print(f"[错误] 文件未找到: {file_path}", file=sys.stderr)
        sys.exit(1)
    except Exception as e:
        print(f"[错误] 读取Excel文件时出错: {e}", file=sys.stderr)
        sys.exit(1)

    print(f"[信息] 使用模型: {model}")
    print(f"[信息] 共找到 {len(unique_inputs)} 条不重复的数据需要处理。")

    results = []
    for i, value in tqdm(enumerate(unique_inputs), total=len(unique_inputs), desc="处理中", unit="条"):
        user_prompt = prompt_template.replace('{{XLSX_VALUE}}', str(value))
        response = get_ai_response_ollama(client, model, user_prompt, i + 1)
        results.append(response)
    
    response_map = {unique_inputs[i]: results[i] for i in range(len(unique_inputs))}

    if output_file:
        try:
            print(f"\n[信息] 处理完成,正在保存结果到 {output_file}...")
            response_col_name = f"{column_name}_AI响应"
            df[response_col_name] = df[column_name].map(response_map)
            df.to_excel(output_file, index=False)
            print(f"[成功] 结果已成功保存到: {os.path.abspath(output_file)}")
        except Exception as e:
            print(f"\n[错误] 保存输出文件时出错: {e}", file=sys.stderr)

def main():
    """
    主函数,用于解析命令行参数并启动处理流程。
    (此函数逻辑无需修改)
    """
    parser = argparse.ArgumentParser(
        description="使用Ollama服务(已按Qwen官方建议优化参数),通过串行请求批量处理Excel文件。",
        formatter_class=argparse.RawTextHelpFormatter
    )
    parser.add_argument("--file", required=True, help="输入的Excel文件路径 (.xlsx)。")
    parser.add_argument("--column", required=True, help="需要处理的数据所在的列名。")
    parser.add_argument("--output", default="output_ollama.xlsx", help="输出的Excel文件名。默认为 'output_ollama.xlsx'。")

    prompt_group = parser.add_argument_group('提示词选项 (必须提供其中之一)')
    prompt_group.add_argument("--prompt", help="直接在命令行中提供提示词模板。\n请使用 '{{XLSX_VALUE}}' 作为占位符。")
    prompt_group.add_argument("--prompt-file", help="包含提示词模板的txt文件路径。")

    api_group = parser.add_argument_group('Ollama API和模型选项')
    api_group.add_argument("--model", required=True, help="要使用的Ollama模型名称(必须与`ollama list`中的名称匹配)。")
    api_group.add_argument("--host", default="http://localhost:11434", help="Ollama服务器的地址。")
    api_group.add_argument("--timeout", type=float, default=60.0, help="API请求的超时时间(秒)。")
    
    args = parser.parse_args()

    prompt_template = ""
    if args.prompt and args.prompt_file:
        print("[错误] --prompt 和 --prompt-file 参数不能同时使用。", file=sys.stderr)
        sys.exit(1)
    if args.prompt:
        prompt_template = args.prompt
    elif args.prompt_file:
        try:
            with open(args.prompt_file, 'r', encoding='utf-8') as f:
                prompt_template = f.read()
            if not prompt_template.strip():
                print(f"[错误] 提示词文件 '{args.prompt_file}' 为空。", file=sys.stderr)
                sys.exit(1)
        except FileNotFoundError:
            print(f"[错误] 提示词文件未找到: {args.prompt_file}", file=sys.stderr)
            sys.exit(1)
    else:
        print("[错误] 必须提供 --prompt 或 --prompt-file 参数之一。", file=sys.stderr)
        sys.exit(1)

    print(f"[信息] 设置API请求超时为: {args.timeout} 秒")
    client = ollama.Client(
        host=args.host,
        timeout=args.timeout,
    )
    
    process_excel_file(
        client=client,
        file_path=args.file,
        column_name=args.column,
        prompt_template=prompt_template,
        output_file=args.output,
        model=args.model
    )

if __name__ == "__main__":
    main()

运行

python excel_c.py  --file "mc.xlsx"  --column "单位详细名称"   --prompt " /no_think 你的任务是从文本中提取并精简核心地名以及单位对应的简称, 然后将它们连接起来,不要带任何标点和多余的文字。例如,输入: 苏州昆山生物医药检测服务有限公司, 输出:苏州昆山生物医药。现在,请处理以下文本:输入: {{XLSX_VALUE}}, 输出:"  --model "dengcao/Qwen3-32B:Q5_K_M"  --output "结果_ollama.xlsx"

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐