基于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.pswp.cn/news/35397.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/35397.shtml
英文地址,請注明出處:http://en.pswp.cn/news/35397.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

VLC播放主要流程

前言 VLC 播放流程大概是先加載解封裝器,然后通過es_out控制所有的stream。然后會加載decoder。最終通過resource文件的方法交給輸出 模塊。下面簡要介紹。 正文 播放器主要分為三層。主要通過兩個接口實現了功能隔離。分別是es_out.c和decoder.c的實現了&#xff1a; //控…

算法練習-搜索 相關

文章目錄 迷宮問題 迷宮問題 定義一個二維數組 m行 * n列 &#xff0c;如 4 5 數組下所示&#xff1a; int arr[5][5] { 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, }; 它表示一個迷宮&#xff0c;1表示墻壁&#xff0c;0表示可以走的路&#xff0c;只…

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個連續的線程…

【Express.js】數據庫初始化

數據庫初始化 在軟件開發階段和測試階段&#xff0c;為了方便調試&#xff0c;我們通常會進行一系列的數據庫初始化操作&#xff0c;比如重置數據表&#xff0c;插入記錄等等&#xff0c;或者在部署階段進行數據初始化的操作 根據前面章節介紹過的 knex.js 和 sequelize.js&…

基于自適應曲線閾值和非局部稀疏正則化的壓縮感知圖像復原研究【自適應曲線閾值去除加性穩態白/有色高斯噪聲】(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;實現…

【實戰講解】數據血緣落地實施

?在復雜的社會分工協作體系中&#xff0c;我們需要明確個人定位&#xff0c;才能更好的發揮價值&#xff0c;數據也是一樣&#xff0c;于是&#xff0c;數據血緣應運而生。 今天這篇文章會全方位的講解數據血緣&#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