Ollama部署internlm2-chat-1.8b:支持批量文档处理的CLI命令行工具开发指南

如果你正在寻找一个既轻量又强大的本地大模型,并且希望它能帮你批量处理文档,那么这篇文章就是为你准备的。今天,我们要一起动手,基于Ollama部署的internlm2-chat-1.8b模型,开发一个实用的命令行工具。这个工具能让你一次性处理多个文档,比如总结、翻译或者提取关键信息,彻底告别手动复制粘贴的繁琐。

internlm2-chat-1.8b是一个拥有18亿参数的对话模型,它在指令遵循和聊天体验上表现不错,关键是它支持超长的上下文,这意味着处理多页文档也不在话下。更重要的是,通过Ollama部署,我们可以轻松地在本地调用它,再结合Python脚本,就能打造一个专属的自动化文档处理助手。

接下来,我会带你从零开始,完成环境搭建、模型部署,并一步步编写一个功能完整的CLI工具。即使你之前没有太多开发经验,跟着步骤走,也能轻松搞定。

1. 环境准备与模型部署

在开始写代码之前,我们需要先把“大脑”——也就是internlm2-chat-1.8b模型——在本地运行起来。这里我们选择Ollama,因为它能让大模型在本地运行变得非常简单。

1.1 安装Ollama

Ollama的安装过程非常直接。根据你的操作系统,选择对应的方法:

  • macOS 和 Linux:打开终端,直接运行以下命令。
  • Windows:需要先安装Windows Subsystem for Linux (WSL2),然后在WSL的终端里运行命令。

安装命令如下:

curl -fsSL https://ollama.ai/install.sh | sh

这条命令会自动下载并安装Ollama。安装完成后,Ollama服务会自动在后台启动。

1.2 拉取并运行internlm2-chat-1.8b模型

模型已经通过Ollama官方集成好了,我们只需要一条命令就能把它“下载”到本地并运行起来。

在终端中执行:

ollama run internlm2:1.8b

第一次运行时会自动从网络拉取模型文件,这可能需要几分钟,取决于你的网速。看到类似 >>> Send a message (/? for help) 的提示符,就说明模型已经在本地成功运行,并进入了一个交互式的聊天界面。

你可以先简单测试一下,输入“你好”,看看它是否能正常回复。测试完成后,按 Ctrl+D 退出交互界面。请注意,退出交互界面并不会停止Ollama服务,模型服务仍在后台运行,等待我们的程序去调用。

至此,我们的模型“引擎”已经就绪。接下来,我们开始搭建处理文档的“车身”。

2. 开发环境与项目初始化

我们的工具将用Python来编写,因为它有丰富的库来处理文件和网络请求。我们先来创建一个干净的项目环境。

2.1 创建项目目录与虚拟环境

首先,找一个你喜欢的位置,创建一个新的项目文件夹,并进入它:

mkdir doc_batch_processor && cd doc_batch_processor

接着,创建一个Python虚拟环境。这能确保我们安装的包不会影响系统其他项目。

python3 -m venv venv

然后激活这个虚拟环境:

  • macOS/Linux: source venv/bin/activate
  • Windows (WSL): source venv/Scripts/activate

激活后,你的命令行提示符前面通常会显示 (venv),表示你已经在这个独立的环境中了。

2.2 安装必要的Python库

我们的工具主要依赖两个库:requests 用于和Ollama API通信,python-dotenv 用于管理配置(可选,但推荐)。

pip install requests python-dotenv

安装完成后,我们可以开始构思和编写工具的核心代码了。

3. 核心工具开发:与模型对话

我们的工具核心是向Ollama服务发送请求,获取模型的回复。我们先实现这个最基础、最重要的功能。

3.1 理解Ollama的API

Ollama在本地启动后,会提供一个HTTP API接口,默认地址是 http://localhost:11434。我们要用的主要端点(Endpoint)是 /api/generate,用于向指定的模型发送文本并生成回复。

这个接口接收一个JSON格式的数据,其中最重要的两个字段是:

  • model: 指定使用哪个模型,这里我们填 "internlm2:1.8b"
  • prompt: 我们发送给模型的指令或问题文本。

3.2 编写模型调用函数

让我们在项目根目录创建一个名为 processor.py 的文件,并写入以下代码:

import requests
import json

class DocProcessor:
    def __init__(self, model_name="internlm2:1.8b", base_url="http://localhost:11434"):
        """
        初始化文档处理器
        :param model_name: 要使用的Ollama模型名称
        :param base_url: Ollama服务的地址
        """
        self.model_name = model_name
        self.base_url = base_url
        self.api_url = f"{base_url}/api/generate"

    def ask_model(self, prompt, stream=False):
        """
        向模型发送单个提示并获取回复
        :param prompt: 发送给模型的文本指令
        :param stream: 是否使用流式响应(对于长文本更友好)
        :return: 模型的回复文本
        """
        payload = {
            "model": self.model_name,
            "prompt": prompt,
            "stream": stream
        }

        try:
            # 发送POST请求到Ollama API
            response = requests.post(self.api_url, json=payload)
            response.raise_for_status()  # 如果请求失败(如4xx,5xx),抛出异常
            result = response.json()

            # 从响应中提取模型生成的回复
            return result.get("response", "").strip()
        except requests.exceptions.ConnectionError:
            print(f"错误:无法连接到Ollama服务,请确保Ollama已在 {self.base_url} 运行。")
            print("提示:你可以在终端运行 'ollama serve' 来启动服务。")
            return None
        except requests.exceptions.RequestException as e:
            print(f"请求API时发生错误:{e}")
            return None
        except json.JSONDecodeError:
            print("错误:无法解析模型的响应。")
            return None

# 快速测试一下
if __name__ == "__main__":
    processor = DocProcessor()
    test_reply = processor.ask_model("用一句话介绍你自己。")
    if test_reply:
        print("模型回复:", test_reply)

这段代码定义了一个 DocProcessor 类,核心是 ask_model 方法。它构造一个请求,发送给本地的Ollama服务,并解析返回的JSON数据,最终提取出模型的文字回复。代码中还包含了一些基本的错误处理,比如网络连接失败或响应格式错误。

现在,运行一下这个脚本:

python processor.py

如果一切正常,你会看到internlm2-chat-1.8b模型用一句话介绍了自己。恭喜你,你已经成功打通了程序和模型之间的通道!

4. 实现批量文档处理功能

单个问答成功了,接下来我们要升级功能:让工具能读取一个文件夹里的所有文本文件,然后对每个文件内容进行批量处理。

4.1 设计处理流程

我们设想的流程是这样的:

  1. 指定输入:用户告诉工具要处理哪个文件夹里的文件。
  2. 读取文件:工具自动找出文件夹里所有的 .txt 文件。
  3. 构建提示:针对每个文件的内容,结合用户的指令(如“请总结”),拼装成完整的提示词发送给模型。
  4. 批量处理:依次处理每个文件,并收集结果。
  5. 输出结果:把每个文件的处理结果保存到一个新的文件中,方便查看。

4.2 扩展文档处理类

我们在 processor.pyDocProcessor 类里添加新的方法来实现上述功能。

import os
from pathlib import Path

class DocProcessor:
    # ... 保持之前的 __init__ 和 ask_model 方法不变 ...

    def process_single_file(self, file_path, instruction):
        """
        处理单个文本文件
        :param file_path: 文本文件的路径
        :param instruction: 对文件内容要执行的指令,例如“总结主要内容”、“翻译成英文”
        :return: 处理后的结果文本
        """
        try:
            with open(file_path, 'r', encoding='utf-8') as f:
                content = f.read()
        except FileNotFoundError:
            print(f"警告:文件 {file_path} 不存在,已跳过。")
            return None
        except UnicodeDecodeError:
            print(f"警告:文件 {file_path} 编码可能不是UTF-8,尝试其他编码或已跳过。")
            return None

        if not content.strip():
            print(f"提示:文件 {file_path} 为空,已跳过。")
            return None

        # 构建给模型的提示词,清晰说明任务
        prompt = f"""请根据以下指令处理后面的文本内容。
指令:{instruction}

文本内容:

{content}


请直接给出处理后的结果:"""
        print(f"正在处理文件:{file_path}")
        result = self.ask_model(prompt)
        return result

    def process_batch(self, input_dir, instruction, output_dir="./output"):
        """
        批量处理一个目录下的所有txt文件
        :param input_dir: 包含txt文件的输入目录
        :param instruction: 处理指令
        :param output_dir: 保存结果的输出目录
        """
        input_path = Path(input_dir)
        output_path = Path(output_dir)
        output_path.mkdir(parents=True, exist_ok=True)  # 创建输出目录

        # 查找所有.txt文件
        txt_files = list(input_path.glob("*.txt"))
        if not txt_files:
            print(f"在目录 {input_dir} 中未找到任何.txt文件。")
            return

        print(f"找到 {len(txt_files)} 个待处理文件。")
        all_results = []

        for txt_file in txt_files:
            result = self.process_single_file(txt_file, instruction)
            if result is not None:
                # 为每个结果文件生成一个对应的输出文件名
                output_file = output_path / f"processed_{txt_file.name}"
                try:
                    with open(output_file, 'w', encoding='utf-8') as f:
                        f.write(f"# 原始文件:{txt_file.name}\n")
                        f.write(f"# 处理指令:{instruction}\n")
                        f.write("-" * 40 + "\n\n")
                        f.write(result)
                    print(f"  结果已保存至:{output_file}")
                    all_results.append((txt_file.name, result))
                except IOError as e:
                    print(f"  写入结果文件时出错:{e}")
            print()  # 空行分隔每个文件的处理日志

        # 生成一个汇总报告
        self._generate_summary(all_results, instruction, output_path)
        print(f"\n批量处理完成!所有结果保存在 {output_dir} 目录中。")

    def _generate_summary(self, results, instruction, output_path):
        """生成一个简单的处理摘要"""
        summary_file = output_path / "processing_summary.md"
        with open(summary_file, 'w', encoding='utf-8') as f:
            f.write(f"# 批量文档处理摘要\n\n")
            f.write(f"**处理指令**:{instruction}\n\n")
            f.write(f"**处理文件数**:{len(results)}\n\n")
            f.write("## 文件列表\n")
            for filename, _ in results:
                f.write(f"- `{filename}` -> `processed_{filename}`\n")
        print(f"处理摘要已生成:{summary_file}")

新增的代码做了以下几件事:

  1. process_single_file: 负责读取单个文件,组合指令和内容形成完整的提示词,然后调用模型。
  2. process_batch: 这是核心批量方法。它扫描输入文件夹,对每个txt文件调用上面的方法,并把模型返回的结果写入到输出文件夹的新文件中。
  3. _generate_summary: 一个辅助方法,生成一个Markdown格式的摘要文件,记录本次处理了哪些文件。

现在,我们的工具已经具备了批量处理的核心能力。让我们给它加上一个方便的命令行界面。

5. 打造易用的命令行界面

为了让工具用起来更方便,我们使用Python内置的 argparse 库来创建一个命令行界面。这样用户就可以直接在终端里指定输入文件夹和指令了。

processor.py 文件末尾,添加以下代码:

import argparse

def main():
    parser = argparse.ArgumentParser(description='基于Ollama internlm2模型的批量文档处理工具')
    parser.add_argument('-i', '--input_dir', required=True,
                        help='输入目录路径,该目录下应包含要处理的.txt文件')
    parser.add_argument('-inst', '--instruction', required=True,
                        help='处理指令,例如:“总结核心观点”、“提取关键词”、“翻译成英文”')
    parser.add_argument('-o', '--output_dir', default='./output',
                        help='输出目录路径,用于保存处理结果(默认:./output)')
    parser.add_argument('-m', '--model', default='internlm2:1.8b',
                        help='指定使用的Ollama模型名称(默认:internlm2:1.8b)')

    args = parser.parse_args()

    print("=" * 50)
    print("启动批量文档处理器")
    print(f"模型:{args.model}")
    print(f"输入目录:{args.input_dir}")
    print(f"处理指令:{args.instruction}")
    print("=" * 50 + "\n")

    # 创建处理器实例并开始批量处理
    processor = DocProcessor(model_name=args.model)
    processor.process_batch(args.input_dir, args.instruction, args.output_dir)

if __name__ == "__main__":
    main()

这个 main 函数定义了工具的命令行参数:

  • -i--input_dir: 必需。指定存放txt文件的文件夹。
  • -inst--instruction: 必需。告诉模型要对文档做什么,比如“总结一下”、“列出要点”。
  • -o--output_dir: 可选。指定结果保存的文件夹,默认是当前目录下的output文件夹。
  • -m--model: 可选。理论上可以指定其他Ollama模型,但这里我们主要用 internlm2:1.8b

6. 实战演练:使用工具处理文档

理论完毕,让我们实际操练一下,看看这个工具到底怎么用。

6.1 准备测试文档

首先,在你的项目目录下,创建一个名为 test_docs 的文件夹,并在里面放几个txt文件。例如:

  • news1.txt:内容是一段科技新闻。
  • report1.txt:内容是一份简短的项目周报。
  • notes1.txt:内容是一些会议纪要。

6.2 运行批量处理命令

打开终端,确保:

  1. 虚拟环境已激活(命令行前有 (venv))。
  2. 当前目录在项目根目录(doc_batch_processor)。
  3. Ollama服务正在运行(如果之前退出了,运行 ollama serve 启动)。

然后执行我们的工具:

python processor.py -i ./test_docs -inst "用中文总结这段文本的核心内容,不超过100字"

你会看到工具开始工作,依次读取每个文件,发送给模型,并打印处理日志。处理完成后,所有结果会保存在 ./output 目录(默认)下。

6.3 查看处理结果

打开 output 文件夹,你会看到:

  • processed_news1.txt, processed_report1.txt, processed_notes1.txt: 每个原始文件对应的处理结果。
  • processing_summary.md: 一个汇总了本次操作信息的Markdown文件。

打开任意一个 processed_xxx.txt 文件,你就能看到internlm2-chat-1.8b模型根据你的指令,对原文生成的总结内容。

6.4 尝试更多指令

你可以灵活变化 -inst 参数,让模型做不同的事情:

  • 提取关键词python processor.py -i ./test_docs -inst "提取本文的3-5个关键词"
  • 翻译python processor.py -i ./test_docs -inst "将以下内容翻译成英文"
  • 问答python processor.py -i ./test_docs -inst "根据文本内容,回答:XXX是什么?"

每次运行,工具都会清空或覆盖 output 文件夹下的内容,生成新的结果。

7. 总结与进阶思考

通过以上步骤,我们成功创建了一个基于本地大模型的批量文档处理CLI工具。我们来回顾一下它的价值和可能的优化方向。

7.1 工具核心价值总结

  1. 本地化与隐私安全:所有文档处理和模型推理都在你的本地电脑上完成,敏感数据无需上传到任何第三方服务器。
  2. 批量处理,效率倍增:一次性处理整个文件夹的文档,自动化替代手动操作,特别适合处理周报、新闻摘要、会议纪要整理等重复性工作。
  3. 灵活可定制:通过修改 instruction 参数,你可以让模型执行总结、翻译、问答、风格改写等多种任务,一个工具应对多种场景。
  4. 轻量易部署:基于Ollama,模型部署极其简单;基于Python,工具本身也易于理解和二次开发。

7.2 可能的优化与扩展方向

你现在拥有的已经是一个可用的工具,但如果你有兴趣,可以从以下几个方向让它变得更强大:

  • 支持更多文件格式:修改 process_batch 方法中的 glob(“*.txt”),可以支持 .md, .pdf (需要 PyPDF2 库), .docx (需要 python-docx 库) 等格式。
  • 添加进度提示与错误重试:对于大量文件,可以添加进度条显示。对于偶尔失败的请求,可以加入重试机制。
  • 调整模型参数:在 ask_model 方法的 payload 中,可以添加 options 字段来调整模型的生成参数,如 temperature (控制创造性)、num_predict (控制生成长度)等,以获得更符合预期的结果。
  • 图形化界面:如果你觉得命令行不够直观,可以使用 tkinterPyQt 库为这个工具包一个简单的图形界面。

这个项目展示了如何将前沿的大模型能力,通过简单的工程手段,转化为解决实际问题的生产力工具。希望它能为你打开一扇门,启发你探索更多本地AI应用的奇妙可能。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐