基于chatgpt动手实现一个ai_translator

动手实现一个ai翻译

前言

最近在极客时间学习《AI 大模型应用开发实战营》,自己一边跟着学一边开发了一个进阶版本的 OpenAI-Translator,在这里简单记录下开发过程和心得体会,供有兴趣的同学参考;

ai翻译程序

版本迭代

在学习课程中呢。老师直播完成了ai翻译程序1.0版本。实现一个比较基础版本的ai翻译程序。

1.0版本

实现的功能:

  • pdf文件解析提取文字和表格
  • 将提取的原始信息发送给chatgpt进行翻译
  • chatgpt返回结果后,将结果保存为pdf或者markdown格式

不足之处

  • 不能保留pdf的原格式
  • 仅支持命令行操作,没有gui
  • 仅支持将中文翻译为英文

任何软件并不是一开始就是完美的,有了这些不足正好可以让我们根据所学的东西,更好的完善它。

2.0版本

实现的功能:

  • 支持图形用户界面(GUI),提升易用性。
  • 添加对保留源 PDF 的原始布局的支持。
  • 服务化:以 API 形式提供翻译服务支持。
  • 添加对其他语言的支持。

2.0要实现的也仅仅是一个开始.

动手实现2.0版本。

最初想先尝试做pdf对原格式的支持,一直没有很好的方案。想着不能一直在这个地方耗着,很多时候可能某一时刻突然灵光一闪就解决了。我先尝试做gui部分。

gui功能的实现

这两天有个同学在群里分享,有个python的gui库streamlit比较简单,并且ui很美观,官方文档也有很多小栗子。
这里放下官方文档链接)st.markdown('1.选择语言模型')st.markdown('2.设置apikey')option = st.selectbox('选择大语言模型?',('OpenAIModel','GLMModel'))api_key = st.text_input('设置apikey',type='password',value='sk-xxx')# clear_button = st.sidebar.button("Clear Conversation", key="clear")model_name = st.selectbox("Choose a model:", ("gpt-3.5-turbo","gpt4"))file_format = st.selectbox("文件的输出类型", ("pdf","text"))

这段代码已经包括完整的侧边栏了,我们来看下运行效果

streamlit run ai-translate.py --runner.fastReruns True

ai-translate.py 注意替换成成实际的文件名,--runner.fastReruns True表示可以修改代码自动生效,调试代码不需要一次次的重启了。
在这里插入图片描述

不出意外你就可以看到侧边栏的内容了

侧边栏完成代码如下:

import streamlit as st
st.set_page_config(page_title="AI-translate",page_icon="👋",
)
with st.sidebar:st.markdown('使用方法')st.markdown('1.选择语言模型')st.markdown('2.设置apikey')option = st.selectbox('选择大语言模型?',('OpenAIModel','GLMModel'))api_key = st.text_input('设置apikey',type='password',value='sk-xxx')# clear_button = st.sidebar.button("Clear Conversation", key="clear")model_name = st.selectbox("Choose a model:", ("gpt-3.5-turbo","gpt4"))file_format = st.selectbox("文件的输出类型", ("pdf","text"))

4.实现主功能页面
设置主功能页面标题和使用方法

st.header('AI Translator')
st.write("# Welcome to AI Translator! 👋")
st.markdown('使用方法')
st.markdown('1.上传需要翻译的文件')
st.markdown('2.静待结果')

添加上传文件的按钮

uploaded_file = st.file_uploader("上传需要翻译的文件",type=['pdf'])

type表示只能上传pdf文件,接下来刷新浏览器看下效果

在这里插入图片描述

整个页面的样式也就出来了,是不是很简单。接下来我们来实现处理上传的文件的逻辑

接下来实现文件处理逻辑
先导入os模块

import os

实现将上传的文件保存到files目录中

if uploaded_file is not None:# st.write(uploaded_file)# To read file as bytes:filename=uploaded_file.namebytes_data = uploaded_file.getvalue()filepath='files'# 检查文件路径是否存在,如果不存在则创建if not os.path.exists(filepath):os.makedirs(filepath)full_filepath=os.path.join(filepath,filename)# Save filewith open(full_filepath, "wb") as f:f.write(bytes_data)st.info('程序处理中。。。', icon="ℹ️")

文件已经保存到目录中了,接下来我们只要将文件丢给翻译程序处理就好了
这里先把页面弄好,之后再填充具体的翻译处理代码。
我们先用一个复制文件的逻辑完成下面的代码

    ### 翻译程序import shutil# 定义源文件路径和目标文件路径source_file = full_filepathfile_name, file_extension = os.path.splitext(source_file)target_file = file_name + '_translated' + file_extension# 使用shutil模块的copy2函数复制文件shutil.copy2(source_file, target_file)st.info('程序完成。', icon="ℹ️")

这个代码主要把源文件复制并重命名了一个,比如源文件是test.pdf目标文件就是test_translated.pdf

实现下载文件按钮

    # 获取文件名和扩展名file_name, file_extension = os.path.splitext(full_filepath)# 构建目标文件名new_pdf_file_path = file_name + '_translated' + file_extensionnewfilename=os.path.split(new_pdf_file_path)[1]# st.download_button('Download some text', text_contents)with open(new_pdf_file_path, "rb") as file:btn = st.download_button(label="Download pdf",data=file,file_name=newfilename,)

现在可以上传文件测试下了
在这里插入图片描述

完整代码如下:

import streamlit as st
import osst.set_page_config(page_title="AI-translate",page_icon="👋",
)
with st.sidebar:st.markdown('使用方法')st.markdown('1.选择语言模型')st.markdown('2.设置apikey')option = st.selectbox('选择大语言模型?',('OpenAIModel','GLMModel'))api_key = st.text_input('设置apikey',type='password',value='sk-xxx')# clear_button = st.sidebar.button("Clear Conversation", key="clear")model_name = st.selectbox("Choose a model:", ("gpt-3.5-turbo","gpt4"))file_format = st.selectbox("文件的输出类型", ("pdf","text"))st.header('AI Translator')
st.write("# Welcome to AI Translator! 👋")
st.markdown('使用方法')
st.markdown('1.上传需要翻译的文件')
st.markdown('2.静待结果')
uploaded_file = st.file_uploader("上传需要翻译的文件",type=['pdf'])
if uploaded_file is not None:# st.write(uploaded_file)# To read file as bytes:filename=uploaded_file.namebytes_data = uploaded_file.getvalue()filepath='files'# 检查文件路径是否存在,如果不存在则创建if not os.path.exists(filepath):os.makedirs(filepath)full_filepath=os.path.join(filepath,filename)# Save filewith open(full_filepath, "wb") as f:f.write(bytes_data)st.info('程序处理中。。。', icon="ℹ️")### 翻译程序import shutil# 定义源文件路径和目标文件路径source_file = full_filepathfile_name, file_extension = os.path.splitext(source_file)target_file = file_name + '_translated' + file_extension# 使用shutil模块的copy2函数复制文件shutil.copy2(source_file, target_file)st.info('程序完成。', icon="ℹ️")# 获取文件名和扩展名file_name, file_extension = os.path.splitext(full_filepath)# 构建目标文件名new_pdf_file_path = file_name + '_translated' + file_extensionnewfilename=os.path.split(new_pdf_file_path)[1]# st.download_button('Download some text', text_contents)with open(new_pdf_file_path, "rb") as file:btn = st.download_button(label="Download pdf",data=file,file_name=newfilename,)

这样就完成了整个gui页面的编写,在上面我们用了一个伪代码逻辑实现了文件的翻译。接下来可以替换成真实的翻译代码
源代码

    ### 翻译程序import shutil# 定义源文件路径和目标文件路径source_file = full_filepathfile_name, file_extension = os.path.splitext(source_file)target_file = file_name + '_translated' + file_extension# 使用shutil模块的copy2函数复制文件shutil.copy2(source_file, target_file)

替换的代码

导入翻译程序代码

from utils import ArgumentParser, ConfigLoader, LOG
from model import GLMModel, OpenAIModel
from translator import PDFTranslator

调用翻译代码

    model = OpenAIModel(model=model_name, api_key=api_key)pdf_file_path = filepath#实例化 PDFTranslator 类,并调用 translate_pdf() 方法translator = PDFTranslator(model)translator.translate_pdf(pdf_file_path, file_format)

完整代码


import streamlit as st
import os
from utils import ArgumentParser, ConfigLoader, LOG
from model import GLMModel, OpenAIModel
from translator import PDFTranslatorst.set_page_config(page_title="AI-translate",page_icon="👋",
)
with st.sidebar:st.markdown('使用方法')st.markdown('1.选择语言模型')st.markdown('2.设置apikey')option = st.selectbox('选择大语言模型?',('OpenAIModel','GLMModel'))api_key = st.text_input('设置apikey',type='password',value='sk-xxx')# clear_button = st.sidebar.button("Clear Conversation", key="clear")model_name = st.selectbox("Choose a model:", ("gpt-3.5-turbo","gpt4"))file_format = st.selectbox("文件的输出类型", ("pdf","text"))st.header('AI Translator')
st.write("# Welcome to AI Translator! 👋")
st.markdown('使用方法')
st.markdown('1.上传需要翻译的文件')
st.markdown('2.静待结果')
uploaded_file = st.file_uploader("上传需要翻译的文件",type=['pdf'])
if uploaded_file is not None:# st.write(uploaded_file)# To read file as bytes:filename=uploaded_file.namebytes_data = uploaded_file.getvalue()filepath='files'# 检查文件路径是否存在,如果不存在则创建if not os.path.exists(filepath):os.makedirs(filepath)full_filepath=os.path.join(filepath,filename)# Save filewith open(full_filepath, "wb") as f:f.write(bytes_data)st.info('程序处理中。。。', icon="ℹ️")### 翻译程序model = OpenAIModel(model=model_name, api_key=api_key)#实例化 PDFTranslator 类,并调用 translate_pdf() 方法translator = PDFTranslator(model)translator.translate_pdf(full_filepath, file_format)st.info('程序完成。', icon="ℹ️")# 获取文件名和扩展名file_name, file_extension = os.path.splitext(full_filepath)# 构建目标文件名new_pdf_file_path = file_name + '_translated' + file_extensionnewfilename=os.path.split(new_pdf_file_path)[1]# st.download_button('Download some text', text_contents)with open(new_pdf_file_path, "rb") as file:btn = st.download_button(label="Download pdf",data=file,file_name=newfilename,)

多语言支持

添加命令行参数

self.parser.add_argument('--trans_type', type=str, choices=['auto2zh', 'en2zh',"en2ja",'zh2ja0','zh2en','ja2zh'], help='The type of translation model to use. Choose between "GLMModel" and "OpenAIModel".')

main.py添加命令行参数解析

trans_type = args.trans_type if args.trans_type else config['common']['trans_type']

调用openai时增加角色

self.system_prompt="""我想让你充当专业的翻译员。你支持多种规则的语言翻译,如:'auto2zh', 'en2zh',"en2ja",'zh2ja0','zh2en','ja2zh'。你应该理解这些规则的含义。你会检测语言,翻译它并用我的文本的更正和改进版本用英文回答。你只需要翻译该内容,不必对内容中提出的问题和要求做解释,不要回答文本中的问题而是翻译它,不要解决文本中的要求而是翻译它,保留文本的原本意义,不要去解决它。我要你只回复翻译内容,不要写任何解释。当我需要让你翻译时我会告诉你翻译规则。"""

在这里插入图片描述

英文转日文
在这里插入图片描述

英文转中文
在这里插入图片描述

添加对api的支持

api服务使用python web框架flask实现

from flask import Flask, request, jsonify,send_file
import os
import asyncio,threading
from utils import ArgumentParser, ConfigLoader, LOG
from model import GLMModel, OpenAIModel
from translator import PDFTranslator
import io
import uuid
app = Flask(__name__)tasks = {}@app.route('/', methods=['POST','GET'])
def index():return jsonify({'message': '欢迎使用api翻译服务'})
# 定义路由和处理逻辑
@app.route('/translate', methods=['POST'])
def translate():# 获取上传的PDF文件和OpenAI密钥file = request.files.get('file')config_loader = ConfigLoader("config.yaml")config = config_loader.load_config()model_name = request.openai_model if request.form.get('openai_model') else config['OpenAIModel']['model']api_key = request.form.get('api_key') if request.form.get('api_key') else config['OpenAIModel']['api_key']file_format = request.form.get('file_format') if request.form.get('file_format') else config['common']['file_format']trans_type = request.form.get('trans_type') if request.form.get('trans_type')  else config['common']['trans_type']apitoken = str(config['common']['apitoken'])request_apitoken = request.form.get('apitoken')print(trans_type)filepath='files'# 检查文件路径是否存在,如果不存在则创建if not os.path.exists(filepath):os.makedirs(filepath)# 验证OpenAI密钥if request_apitoken != apitoken:print(f"###{request_apitoken}###",f'###{apitoken}###')print(type(request_apitoken),type(apitoken))return jsonify({'error': 'apitoken 验证失败'})if not file:return jsonify({'error': '请上传需要翻译的文件,仅限于pdf'})else:file.save('files/' + file.filename)full_filepath=f'files/{file.filename}'# # 调用翻译函数进行翻译model = OpenAIModel(model=model_name, api_key=api_key)# # 实例化 PDFTranslator 类,并调用 translate_pdf() 方法translator = PDFTranslator(model)task_id = str(uuid.uuid4())thread = threading.Thread(target=translator.translate_pdf, args=(full_filepath,file_format,trans_type))thread.start()tasks[task_id] = thread#task = asyncio.create_task(translate_file(task_id,full_filepath))#task=translate_file(task_id, full_filepath)# 返回任务ID给客户端return jsonify({'task_id': task_id})#return send_file(full_filepath, as_attachment=True)
@app.route('/translated/<task_id>', methods=['GET'])
def get_translated_pdf(task_id):# 检查任务ID是否存在if task_id not in tasks:return jsonify({'message': 'Invalid task ID'})thread = tasks[task_id]task_status=thread.is_alive()if task_status is True:message="翻译任务进行中"else:message="翻译结束"return jsonify({'message': message})if __name__ == '__main__':app.run(port=5002)

在请求服务之前需在配置文件中配置apitoken。


common:apitoken: 123456

启动api服务

python ai_translator/AI-translate-api.py 

请求api服务-
创建翻译任务
在这里插入图片描述

在这里插入图片描述

根据返回的任务id查询任务状态
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/35397.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Synchronized八锁

/** * Description: 8 锁 * 1 标准访问&#xff0c;先打印短信还是邮件 ------sendSMS ------sendEmail 2 停 4 秒在短信方法内&#xff0c;先打印短信还是邮件 ------sendSMS ------sendEmail 3 新增普通的 hello 方法&#xff0c;是先打短信还是 hello ------getHello ------…

Idea中使用statement接口对象,显示mysql版本号,所有库和表名

使用statement 接口对象&#xff0c;进行以下操作&#xff1a; 显示数据库版本号显示所有库显示所有库中的table表 显示数据库版本号&#xff1a; public class StatementDemo {Testvoid showall(){try{Statement st conn.createStatement();ResultSet rs st.executeQuery(…

pytest fixture 常用参数

fixture 常用的参数 参数一&#xff1a;autouse&#xff0c;作用&#xff1a;自动运行&#xff0c;无需调用 举例一&#xff1a;我们在类中定义一个function 范围的fixture; 设置它自动执行autouseTrue&#xff0c;那么我们看下它执行结果 输出&#xff1a; 说明&#xff1a;…

Leetcode-每日一题【剑指 Offer 12. 矩阵中的路径】

题目 单词必须按照字母顺序&#xff0c;通过相邻的单元格内的字母构成&#xff0c;其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。 例如&#xff0c;在下面的 34 的矩阵中包含单词 "ABCCED"&#xff08;单词中的字母…

CUDA执行模型

一、CUDA执行模型概述 二、线程束执行 1. 线程束与线程块 线程束是SM中基本的执行单元。 当一个线程块的网格被启动后&#xff0c;网格中的线程块分布在SM中。 一旦线程块被调度到一个SM中&#xff0c;线程块中的线程会被进一步划分成线程束。 一个线程束由32个连续的线程…

基于自适应曲线阈值和非局部稀疏正则化的压缩感知图像复原研究【自适应曲线阈值去除加性稳态白/有色高斯噪声】(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

什么是媒体代发布?媒体代发布注意事项

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 媒体代发布是指将新闻稿或其他宣传内容委托给专业的媒体代理机构或公司进行发布和推广的活动。这些机构通常拥有丰富的媒体资源、人脉和经验&#xff0c;能够更好地将信息传递给目标受众…

C语言 指针与内存之间的关系

一、内存与字节 一个内存单元一个字节一个地址 整型 int 类型中int类型的字节数是4 且一个字节表示八个bite位 一个二进制数位有着32个bite 所以又可以表示为&#xff1a;一个字节 8个比特位 32位数的二进制数位的八分之一 例如&#xff1a; int a 10&#xff1b; 该表达式…

项目实战 — 消息队列(9){编写demo程序}

消息队列服务器核心功能就是&#xff0c;提供了虚拟主机&#xff0c;交换机&#xff0c; 队列&#xff0c;消息等概念的管理&#xff0c;实现三种典型的消息转发方式&#xff0c;可以实现跨主机/服务器之间的生产者消费模型。 这里&#xff0c;就编写一个demo&#xff0c;实现…

JAVA多线程和并发基础面试问答(翻译)

JAVA多线程和并发基础面试问答(翻译) java多线程面试问题 1. 进程和线程之间有什么不同&#xff1f; 一个进程是一个独立(self contained)的运行环境&#xff0c;它可以被看作一个程序或者一个应用。而线程是在进程中执行的一个任务。Java运行环境是一个包含了不同的类和程序…

苏州OV泛域名RSA加密算法https

RSA加密算法是一种非对称加密算法&#xff0c;它被广泛应用于信息安全领域。与对称加密算法不同&#xff0c;RSA加密算法使用了两个密钥&#xff0c;一个公钥和一个私钥。公钥可以公开&#xff0c;任何人都可以使用它加密信息&#xff0c;但只有私钥的持有者才能解密信息。RSA加…

php如何对接伪原创api

在了解伪原创api的各种应用形态之后&#xff0c;我们继续探讨智能写作背后的核心技术。需要说明的是&#xff0c;智能写作和自然语言生成、自然语言理解、知识图谱、多模算法等各类人工智能算法都有紧密的关联&#xff0c;在百度的智能写作实践中&#xff0c;常根据实际需求将多…

全球劳动力革命,Papaya Global 打破薪资界限

员工需求和劳动力结构的进一步变化&#xff0c;只会增加对更加自动化和全面的全球薪资解决方案的需求。 远程工作潮流与全球劳动力的蓬勃发展&#xff0c;使得企业在全球范围内&#xff0c;寻找最优秀的人才成为可能。然而&#xff0c;随之而来的复杂薪资管理挑战&#xff0c;也…

优雅地处理RabbitMQ中的消息丢失

目录 一、异常处理 二、消息重试机制 三、错误日志记录 四、死信队列 五、监控与告警 优雅地处理RabbitMQ中的消息丢失对于构建可靠的消息系统至关重要。下面将介绍一些优雅处理消息丢失的方案&#xff0c;包括异常处理、重试机制、错误日志记录、死信队列和监控告警等。…

BUUCTF题目Web部分wp(持续更新)

关于SQL注入的一些通用办法 可以访问哪些表 如有权限&#xff0c;查询当前用户可以访问的所有表 --Oracle查询当前用户可访问的所有表 select owner&#xff0c; table_name from all_tables order by table_name; --MySQL查询用户可访问的所有数据库和表 select table_sche…

爬虫017_urllib库_get请求的quote方法_urlencode方法_---python工作笔记036

按行来看get请求方式 比如这个地址 上面这个地址复制粘贴过来以后 可以看到周杰伦变成了一堆的Unicode编码了 所以这个时候我们看,我们说https这里,用了UA反爬,所以这里 我们构建一个自定义的Request对象,里面要包含Us

电脑mfc140u.dll丢失的怎么办呢?这个方法亲测可以解决

修复mfc140u.dll是我最近遇到的一个技术问题&#xff0c;虽然在解决过程中遇到了一些困难&#xff0c;但最终的成功修复让我对技术的力量有了更深的体会。 首先&#xff0c;我想谈谈遇到问题时的困惑。当我尝试运行一个应用程序时&#xff0c;突然弹出一个错误提示&#xff0c;…

YAMLException: java.nio.charset.MalformedInputException: Input length = 1

springboot项目启动的时候提示这个错误&#xff1a;YAMLException: java.nio.charset.MalformedInputException: Input length 1 根据异常信息提示&#xff0c;是YAML文件有问题。 原因是yml配置文件的编码有问题。 需要修改项目的编码格式&#xff0c;一般统一为UTF-8。 或…

TENNECO EDI 项目——X12与XML之间的转换

近期为了帮助广大用户更好地使用 EDI 系统&#xff0c;我们根据以往的项目实施经验&#xff0c;将成熟的 EDI 项目进行开源。用户安装好知行之桥EDI系统之后&#xff0c;只需要下载我们整理好的示例代码&#xff0c;并放置在知行之桥指定的工作区中&#xff0c;即可开始使用。 …

YOLOv5入门实践(3)— 手把手教你如何去划分数据集

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。数据集标注完成之后&#xff0c;下一步就是对这些数据集进行划分了。面对繁杂的数据集&#xff0c;如果手动划分的话&#xff0c;不仅麻烦而且不能保持随机性。本节课就给大家介绍一种方法&#xff0c;即使用代码去划分数据…