前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >不用GPU搭建一个漫画自动翻译网站

不用GPU搭建一个漫画自动翻译网站

原创
作者头像
嘉文2demo
修改2023-07-12 12:23:40
1.1K0
修改2023-07-12 12:23:40
举报
文章被收录于专栏:玩转Lighthouse玩转Lighthouse

简介

最近因为看《我心里危险的东西》和《放学后失眠的你》然后因为太喜欢了就去看漫画了,后来又一发不可收拾就去追更漫画了。还追了一部没找到熟肉的条漫。条漫是英语还好,我自己虽然只是四级水平的英语能力,但是可以勉强能看懂台词,实在看不懂的可以去直接各个翻译平台就行了。但是日漫还有一些本子来说说,我完全不认识日文,想去平台翻译也不太好翻译。因为漫画不是小说,文字都是图片形式的,自己去做OCR识别再去翻译属实是折磨中的折磨。因此我就到处找能用的软件/平台终于让我找到了这个程序。试用了一下就觉得这就是我要的。

这个项目就是:https://github.com/zyddnys/manga-image-translator

硬件需求

理论上来说还是推荐大家使用GPU服务器提供服务,这样速度会更快。还有就是推荐用海外平台。主要是为了方便用一些海外服务商的翻译服务。当然,也可以国内直接搭建,家用电脑也可以。

我们这里用的是

腾讯云的硅谷轻量服务器(2C2G)

环境配置

方面主要是python环境推荐3.8及以上版本。

可以通过python --version进行查看默认版本号。如果遇到提示版本号2.7或者提示下图的

python :command not found可以尝试使用

代码语言:txt
复制
python3 --version

确定python3版本符合要求之后我们还需要进行额外的一步操作,让linux系统下的默认的python命令绑定到python3上。

1、如果你的系统只有python3:

1.1 首先,确认已安装的 Python3 版本和其安装路径。可以通过以下命令查找 Python3 的安装路径:

代码语言:txt
复制
which python3
#/usr/bin/python3

1.2 假设 Python3 的路径为 /usr/bin/python3(如果实际路径不同,请将以下步骤中的路径更改为实际路径),你可以运行以下命令将 Python3 添加为系统的可选择 Python 版本:

代码语言:txt
复制
update-alternatives --install /usr/bin/python python /usr/bin/python3 1

这个命令的意思是,将 /usr/bin/python3 作为可供选择的 Python 版本,并为它设置优先级为 1。

1.3 运行以下命令,你可以看到所有可供选择的 Python 版本:

代码语言:txt
复制
update-alternatives --config python

在出现的列表中,选择 Python3 作为默认版本。

2、同时有python2,python3

还是一样的操作

代码语言:txt
复制
which python2
which python3

然后,你需要使用 update-alternatives 命令将两个版本的 Python 添加到可选项中。你可以给它们设置一个优先级,数值越大,优先级越高。在这个例子中,我们将给 Python3 设置更高的优先级,使其成为默认版本:

代码语言:txt
复制
update-alternatives --install /usr/bin/python python /usr/bin/python2 1
update-alternatives --install /usr/bin/python python /usr/bin/python3 2

最后再选择python3版本的作为默认版本即可

代码语言:txt
复制
update-alternatives --config python

项目搭建

接下来就是重头戏了。

添加swap

首先给你的服务器添加swap。因为这个项目还是比较吃内存的,我个人推荐内存+swap最好大于8GB。这里我添加了8GB的swap

按照以下的命令一次复制粘贴执行即可

代码语言:txt
复制
fallocate -l 8G /swapfile
#创建swap文件
chmod 600 /swapfile
#权限设置成只有root用户才能读写
mkswap /swapfile
#设置成swap空间
swapon /swapfile
#启用swap文件
swapon --show
#查看是否成功启用
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
#重启有效

项目配置

首先我们需要编译安装pydensecrf,注意一定要先安装这个,不然可能会导致奇奇怪怪的问题

代码语言:txt
复制
#海外服务器
pip install git+https://github.com/lucasb-eyer/pydensecrf.git

#国内服务器
pip install git+https://ghproxy.com/https://github.com/lucasb-eyer/pydensecrf.git

这个速度可能会有点慢,稍微等几分钟就行。

再拉取项目仓库:

代码语言:txt
复制
#海外服务器
git clone https://github.com/zyddnys/manga-image-translator.git

#国内服务器
git clone https://ghproxy.com/https://github.com/zyddnys/manga-image-translator.git

安装依赖:

代码语言:txt
复制
cd manga-image-translator
pip install -r requirements.txt

等依赖安装的过程之中我们可以先看下面的操作。

防火墙设置

项目可以命令行运行也可以web运行,我们时需要web服务,方便在线访问的。项目web模式会默认运行在5003端口,所以我们需要先去服务器控制台进行端口开放,如果使用了宝塔服务器还需要去宝塔后台同样进行操作。

腾讯云轻量服务器控制台:https://console.cloud.tencent.com/lighthouse/instance

选择项目服务器,点击防火墙

开放5003端口协议选tcp

宝塔面板开放端口,操作都是类似的,但是宝塔强制要求备注

防火墙设置完成之后,项目依赖应该也已经完成了。

项目运行

我们是CPU服务器,需要提供web在线服务。

所以我们可以直接用命令行命令,如果是腾讯云的GPU服务器,在初始化的时候会自动安装cuda,运行命令也只需要加上--use-cuda就可以了

代码语言:txt
复制
python -m manga_translator --verbose --mode web
python -m manga_translator --verbose --mode web --use-cuda

这时候你可以直接在宝塔面板设置反向代理就可以通过域名访问了

如果你不需要域名,要直接通过IP:端口来访问,还需要给命令指定host才行,否则无法访问公网IP:端口,内网IP可在服务器控制台查看,也可以通过ifconfig命令查看一般都是eth0的ip

代码语言:txt
复制
python -m manga_translator --verbose --mode web --host 内网IP
# python -m manga_translator --verbose --mode web --host 10.0.4.14

这样就可以直接在公网通过公网ip:5003来访问web服务了。

我个人偏向于使用离线翻译节约成本,需要其他翻译器的可以查看官方文档添加api key。

翻译器列表:

我用的是m2m100_big。

首次运行会下载对应翻译模型,OCR包等大文件

你可以下载对应文件然后上传到对应目录,也可以先看一下是需要下哪些文件,可以提前下好

下载文件都是github文件,所以都可以通过加速链接下载源文件到指定文件夹

加速下载方式:

代码语言:txt
复制
wget https://ghproxy.com/+github-url -P 文件夹
# wget https://ghproxy.com/https://github.com/zyddnys/manga-image-translator/releases/download/beta-0.3/inpainting_lama_mpe.ckpt -P /home/lighthouse/manga-image-translator/models/inpainting

然后就可以看到项目运行了

整个工作流流程大概分为以下几个:

上传图片——ocr提取原文——翻译——重新绘图——返回图片

其中可能涉及到分辨率放大处理之类的

下面是我的测试效果:

原图

完成图

我对这个效果还是很满意的。

批量翻译

批量翻译只支持命令行翻译

命令行翻译单一图片

代码语言:txt
复制
# 如果机器有支持 CUDA 的 NVIDIA GPU,可以添加 `--use-cuda` 参数
# 使用 `--use-cuda-limited` 将需要使用大量显存的翻译交由CPU执行,这样可以减少显存占用
# 使用 `--translator=<翻译器名称>` 来指定翻译器
# 使用 `--target-lang=<语言代码>` 来指定目标语言
# 将 <图片文件路径> 替换为图片的路径
# 如果你要翻译的图片比较小或者模糊,可以使用upscaler提升图像大小与质量,从而提升检测翻译效果
python -m manga_translator --verbose --use-cuda --translator=google --target-lang=CHS -i <path_to_image_file>
# 结果会存放到 result 文件夹里

批量翻译只要加上--mode batch就可以了

代码语言:txt
复制
# 其它参数如上
# 使用 `--mode batch` 开启批量翻译模式
# 将 <图片文件夹路径> 替换为图片文件夹的路径
python -m manga_translator --verbose --mode batch --use-cuda --translator=google --target-lang=CHS -i <图片文件夹路径>
# 结果会存放到 `<图片文件夹路径>-translated` 文件夹里

web服务持续运行

这里推荐两种方法:screen和nohup

1、screen

代码语言:txt
复制
#安装screen
apt install screen -y
# 创建一个shell窗口
screen -R manga
#然后在直接运行web服务命令即可。CTRL + A ,CTRL + D让这个shell窗口挂载运行。
下次需要进入这个窗口可以再次输入`screen -R manga`进入

2、nohup

代码语言:txt
复制
nohup python -m manga_translator --verbose --mode web > output.log 2>&1 &

这个命令作用是把所有日志都输出到output.log中,最后的&表示让这个命令在后台运行

其他

项目地址:https://github.com/zyddnys/manga-image-translator

项目官方演示站:https://touhou.ai/imgtrans/

项目其他前端:https://github.com/VoileLabs/cotrans

油猴脚本

以下为nhentai.net的翻译脚本,要先自建服务才能使用。由于网站的CORS问题,所以需要额外安装一个插件:CORS插件并且在nhentai上开启。有能力的可以自行根据下面代码进行更改

代码语言:txt
复制
// ==UserScript==
// @name         Manga Translation
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  Translate manga using a remote translation service
// @author       You
// @match        https://nhentai.net/*
// @grant        GM.xmlHttpRequest
// @grant        unsafeWindow.fetch
// ==/UserScript==

(function() {
    'use strict';

    // Create a select element for the translator
    var translatorSelect = document.createElement('select');
    ['sugoi', 'm2m100', 'm2m100_big', 'none', 'original', 'google', 'youdao', 'baidu', 'deepl', 'gpt3', 'gpt3.5', 'gpt4', 'papago', 'offline'].forEach(function(translator) {
        var option = document.createElement('option');
        option.value = translator;
        option.textContent = translator;
        translatorSelect.appendChild(option);
    });
    translatorSelect.value = 'm2m100_big'; // Set the default translator

    // Create a select element for the target language
    var languageSelect = document.createElement('select');
    ['CHS', 'CHT', 'CSY', 'NLD', 'ENG', 'FRA', 'DEU', 'HUN', 'ITA', 'JPN', 'KOR', 'PLK', 'PTB', 'ROM', 'RUS', 'ESP', 'TRK', 'VIN'].forEach(function(lang) {
        var option = document.createElement('option');
        option.value = lang;
        option.textContent = lang;
        languageSelect.appendChild(option);
    });

    // Insert a "Translate" button into the page
    var button = document.createElement('button');
    button.textContent = 'Translate';
    button.addEventListener('click', function() { translate(translatorSelect.value, languageSelect.value); });

    // Create a container for the button and selects and append them
    var container = document.createElement('div');
    container.style.position = 'fixed';
    container.style.bottom = '10px';
    container.style.right = '10px';
    container.appendChild(button);
    container.appendChild(document.createTextNode(' Translator: '));
    container.appendChild(translatorSelect);
    container.appendChild(document.createTextNode(' Language: '));
    container.appendChild(languageSelect);
    document.body.appendChild(container);

    // Event handler for the "Translate" button
    function translate(translator, language) {
        var img = document.querySelector('img[src*="galleries"]'); // Select the image with 'galleries' in the source URL

        if (!img) {
            return;
        }

        // Use fetch API to get the image blob
        unsafeWindow.fetch(img.src)
        .then(response => response.blob())
        .then(blob => {
            // Create a FormData object and append the image blob and additional parameters
            var formData = new FormData();
            formData.append('file', blob, 'image.jpg');
            formData.append('size', 'M');
            formData.append('detector', 'auto');
            formData.append('direction', 'auto');
            formData.append('translator', translator);
            formData.append('tgt_lang', language);

            // Create a new element to display the status
            var statusDiv = document.createElement('div');
            statusDiv.style.position = 'absolute';
            statusDiv.style.zIndex = 1000;
            statusDiv.style.backgroundColor = 'rgba(0, 0, 0, 0.5)';
            statusDiv.style.color = 'white';
            statusDiv.style.padding = '5px';
            statusDiv.textContent = 'Uploading...';
            img.parentElement.appendChild(statusDiv);

            // Send the POST request
            GM.xmlHttpRequest({
                method: 'POST',
                url: 'http://127.0.0.1:5003/submit',
                data: formData,
                onload: function(response) {
                    var taskId = JSON.parse(response.responseText).task_id; // Parse the task ID from the response
                    statusDiv.textContent = 'Translating...';

                    // Wait for the translation to be done and then replace the image
                    var checkInterval = setInterval(function() {
                        GM.xmlHttpRequest({
                            method: 'GET',
                            url: 'http://127.0.0.1:5003/task-state?taskid=' + taskId,
                            onload: function(response) {
                                var res = JSON.parse(response.responseText);
                                statusDiv.textContent = 'Status: ' + res.state;
                                if (res.finished) {
                                    clearInterval(checkInterval);
                                    img.src = 'http://127.0.0.1:5003/result/' + taskId + '/final.jpg';
                                    statusDiv.parentElement.removeChild(statusDiv);
                                }
                            }
                        });
                    }, 1000);
                }
            });
        });
    }
})();

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简介
  • 硬件需求
  • 环境配置
  • 项目搭建
    • 添加swap
      • 项目配置
      • 防火墙设置
      • 项目运行
        • 批量翻译
          • web服务持续运行
          • 其他
          • 油猴脚本
          相关产品与服务
          轻量应用服务器
          轻量应用服务器(TencentCloud Lighthouse)是新一代开箱即用、面向轻量应用场景的云服务器产品,助力中小企业和开发者便捷高效的在云端构建网站、Web应用、小程序/小游戏、游戏服、电商应用、云盘/图床和开发测试环境,相比普通云服务器更加简单易用且更贴近应用,以套餐形式整体售卖云资源并提供高带宽流量包,将热门开源软件打包实现一键构建应用,提供极简上云体验。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档