Caution
- It is currently under development, and the stored data of this version is not compatible with that before V0.4.0. To use the old version, please go here.
- We DO NOT provide any RenPy game files, and the program is designed only for the convenience of developers to manage translations. The user shall be held responsible for all the consequences arising from using this program.
There are two tools to help you translate a RenPy Game:
Name | Features | Supported Translation Engines |
---|---|---|
RealTime Translator | Translate what you see. Very easy to use. See this. | ☑️OpenAI Endpoint, ☑️UlionTse/translators |
Commandline Translation Toolkit | Translate all texts in the game. It take a few steps to translate. It is mainly used to manage translations among RenPy games. There are many use command to manage these translations. See this. | ☑️OpenAI Endpoint, ☑️UlionTse/translators, ☑️Google Translation, ☑️HTML Translation, ☑️Excel Translation, ☑️AI Translation Models |
Click to show
-
Web Translation, only supports google translation:
translate {index_or_name} -t web -n google -l {lang}
-
AI Translation:
translate {index_or_name} -t ai -n mbart50 -l {lang}
-
Inspect translated texts: Use
inspect
command to find lost variables, style tags, and escape characters in translated texts (e.g., [var], {font}):inspect {index_or_name} -l {lang}
. After you fix them in the generated Excel file, useupdateexcel
command to update these texts:updateexcel {index_or_name} -l {lang}
-
[0.4.1] Reuse pre-translated string texts: You can place some rpy files containing pre-translated string texts of language {lang} under
resources/tl/{lang}
. String texts are like:translate schinese strings: # renpy/common/00accessibility.rpy:28 old "Self-voicing disabled." new "机器朗读已禁用。" # renpy/common/00accessibility.rpy:29 old "Clipboard voicing enabled. " new "剪贴板朗读已启用。"
In addition, we also have placed many rpy files with pre-translated string texts (These files are copied from RenPy). After executing
import
command (e.g.,i {projrct} -l {lang}
), the pre-translated string texts will be used to update imported string texts if the specified {lang} parameter matches the name of the subdirectory inresources/tl
. If you don't want to reuse these translations, please append the-nr
option toimport
command:i {projrct} -l {lang} -nr
Note that, the source langauge of these provided rpy files is English. It means that there rpy files provide translations from English to other languages. The root dir of these files can be configed by
index.recycle_dir
in config.yaml. -
[0.4.1] Open the location of RenPy game or save file (Windows OS Only): Use the new
open
command to pen the location of a RenPy game associated the TranslationIndex. Some commands for saving file (e.g.,savehtml
,saveexcel
,dumpexcel
), will automatically open the saved file's location after the file is saved. To prevent the behavior, please append the-nw
option to these command. -
[0.4.1] UlionTse/translators:
translate {index_or_name} -t ts -n bing -l {lang}
-
[0.4.2] Use
new_file
command to create a FileTranslationIndex from a single file:nf {file_path} -s {type}
, where{type}
is the translation tool which generated the file, and you can pick from:mt
(ManualTransFile.json generated by MTool.),xu
(_AutoGeneratedTranslations.txt generated by XUnity Auto Translator),tp
(xlsx/xls file generated by Translator++). Then, use other command to manage FileTranslationIndexes as usual. The following commands are not available for FileTranslationIndexes:inject
,count
. You learn more about it bynf -l
andnf -h
command. -
[0.4.2] You can use
-a
option to enable AI translation and UlionTse/translators translation to load translation settings from the config file automatically. It reduces some args to enter for these commands.Auto UlionTse/translators translation:
t {index_or_name} -t ts -l {lang} -a
. Default args in config.yaml:translators: api_name: 'bing' # Language code can be found at: resources/translation/translators_langcode.txt from_language: 'auto' to_language: 'zh-Hans'
Auto AI translation:
t {index_or_name} -t ai -l {lang} -a
. Default args in config.yaml:ai: # available models: 'm2m100', 'mbart50', 'nllb200' model_name: 'mbart50' batch_size: 2 # Language code can be found at: resources/translation/dl-translate_langcode.txt from_language: 'English' to_language: 'Chinese'
-
[0.4.3] Now you can save translations as a TranslationIndex in the RealTime Translator, which means that you can process these translations toolkit to process these translations.
-
[0.4.4] Now you can use the OpenAI Endpoint to translate. See Use OpenAI Endpoint.
-
[0.4.5] New command 'llm translate' is available, which uses the OpenAI Endpoint to improve translation quality and reduce translation errors. Usage:
llm_translate {index or name} -l {lang} -m {model_name} -t {target_lang}
, or using default config:llm_translate {index or name} -l {lang} -a
. -
[0.4.5-fix] 1. Fix bugs. 2. You can filter unwanted text in RealTime Translator.
Download exe.7z
and libs.7z
from Release, then unzip them. Open the server_ui.exe
.
You can see the following UI:
Then perform the following steps to translate a RenPy game:
-
Click the "Select" button to select your RenPy game path:
-
Click the "Injection" button for game detection and code injection:
-
Configure the translator and font in the following configuration pages (Note that, Provider=Foo is used for testing and does not support translation):
-
Click the "Start" button to start the translation server:
-
Click the "Start" button under GAME page to start the game, or manually start the game:
-
During running the game, you may feel a lag, which is caused by requesting translation.
You will also find that the translation result is not displayed when playing game for the first time. This is because a large number of translated texts are currently in the queue, so you need to wait for the value of the queue reduced to 0 and re-enter the game scene.
Finally, you can save the current translation results to the game by clicking the "Save translations" button. By doing this, even if you close the translator, you can still load translations from the translation cache.
This translation cache file projz_translations.json
will be saved to the game root. Please note that, do not click the "Undo injection" button as this will disable our translation code.
To use the translation cache file, you need to reopen the game and close our translator. In addition, our translator will automatically load this translation cache file from the game directory (after clicking the "Injection" button) to avoid duplicating translations.
At present, this translator is only a demo and will be integrated with our translation tools in the future.
You can also save the current translation as a TranslationIndex by clicking the "Save TranslationIndex" button, so that you can use various commands for FileTranslationIndex to quickly process these translations in our Commandline Translation Toolkit.
- Create a py file in translation_provider. Then, create your class which inherits the
Provider
class in base.py, and implements these following methods (reload_config()
is not a member method inProvider
class, which is used to reload config to get the newest values ifReload config file
button is clicked.):
from trans import Translator
from typing import List, Tuple
from trans.translators_api import TranslatorsTranslator
from translation_provider.base import Provider, register_provider
import translators as ts
class TranslatorsApi(Provider):
def __init__(self):
super().__init__()
self.trans_kwargs = None
self.tconfig = None
self.reload_config()
def reload_config(self):
self.tconfig = self.config['translator']['translators']
self.trans_kwargs = self.tconfig.get('translate_text', {})
def api_names(self) -> List[str]:
return list(ts.translators_pool)
def default_api(self) -> str:
self.reload_config()
return self.tconfig.get('api_name', 'bing')
def default_source_lang(self) -> str:
self.reload_config()
return self.tconfig.get('from_language', 'auto')
def default_target_lang(self) -> str:
self.reload_config()
return self.tconfig['to_language']
def languages_of(self, api: str) -> Tuple[List[str], List[str]]:
langs = sorted(list(ts.get_languages(api).keys()))
return ['auto'] + langs, langs
def translator_of(self, api: str, source_lang: str, target_lang: str) -> Translator:
if api in self.api_names():
s, t = self.languages_of(api)
if source_lang in s and target_lang in t:
return TranslatorsTranslator(api, source_lang, target_lang, self.trans_kwargs)
return None
# Register your translation API
register_provider('translators', TranslatorsApi())
- Import your py file in __init__.py:
import logging
import translation_provider.base
# You should import it with a try-except block
try:
import translation_provider.translators
except Exception as e:
logging.exception(e)
try:
import translation_provider.closeapi
except Exception as e:
logging.exception(e)
- Run:
python3 server_ui.py
Note that, this Commandline Translation Toolkit is not a one-button translator for RenPy games, and it still requires a few steps to translate. It is mainly used to manage translations among RenPy games, and to translate texts. The main functions are as follows:
- Import and generate translations without the RenPy SDK.
- Manage translations of various languages among RenPy games.
- Export your translations to a Excel/Json/HTML file.
- Translate texts with free resources.
- Inspect translated texts for finding lost variables, style tags, and escape characters. Learn more: What's new 3.
- Provide the I18n plugin to change language or font in game.
- Customize your translation API. Learn more: Customize your translation API
- Reuse pre-translated string texts when importing translations. Learn more: What's new 4
- Import translations from a single file generated by other translation tools (MTool, Translator++, and XUnity Auto Translator). Learn more: What's new 7
All commands in this tool:
+--------------------+---------------------------------------------------------------------------+
| Command name | Description |
+--------------------+---------------------------------------------------------------------------+
| new | n | Create a TranslationIndex from the given game path. |
+--------------------+---------------------------------------------------------------------------+
| new_file | nf | Create a FileTranslationIndex from the given file path. |
+--------------------+---------------------------------------------------------------------------+
| import | i | Import translations of the given language into this TranslationIndex. |
| | (Base injection required) |
+--------------------+---------------------------------------------------------------------------+
| generate | g | Generate translations of the given language from this TranslationIndex. |
| | (Base injection required) |
+--------------------+---------------------------------------------------------------------------+
| count | c | Print a count of missing translations of the given language. |
| | (Base injection required) |
+--------------------+---------------------------------------------------------------------------+
| open | o | Open the location of the RenPy game associated with the TranslationIndex. |
| | (Windows OS Only) |
+--------------------+---------------------------------------------------------------------------+
| lint | Run lint for checking script. |
+--------------------+---------------------------------------------------------------------------+
| launch | Launch the RenPy game associated with the TranslationIndex. |
| | (Windows OS Only) |
+--------------------+---------------------------------------------------------------------------+
| inject | ij | Inject our code or i18n plugins into the game. |
+--------------------+---------------------------------------------------------------------------+
| translate | t | Translate untranslated lines of the given language |
| | using the specified translator. |
+--------------------+---------------------------------------------------------------------------+
| llm_translate | lt | Translate untranslated lines of the given language |
| | using the LLM Augment Translating. |
+--------------------+---------------------------------------------------------------------------+
| ls | l | List existing TranslationIndexes. |
+--------------------+---------------------------------------------------------------------------+
| del | Delete the TranslationIndex. |
+--------------------+---------------------------------------------------------------------------+
| clear | Clear all existing TranslationIndex. |
+--------------------+---------------------------------------------------------------------------+
| discard | Discard translations of the given language. |
+--------------------+---------------------------------------------------------------------------+
| rename | Rename a name of language translations. |
+--------------------+---------------------------------------------------------------------------+
| copy | Copy translations of the given language. |
+--------------------+---------------------------------------------------------------------------+
| mark | Mark all untranslated lines as translated ones. |
+--------------------+---------------------------------------------------------------------------+
| unmark | Mark all translated lines as untranslated ones. |
+--------------------+---------------------------------------------------------------------------+
| upstats | Update translation stats of the specified TranslationIndex. |
+--------------------+---------------------------------------------------------------------------+
| merge | m | Merge translations of the given language from another TranslationIndex. |
+--------------------+---------------------------------------------------------------------------+
| savehtml | sh | Save untranslated lines of the given language to a html file. |
+--------------------+---------------------------------------------------------------------------+
| loadhtml | lh | Load translated lines of the given language from a html file. |
+--------------------+---------------------------------------------------------------------------+
| saveexcel | se | Save untranslated lines of the given language to a excel file. |
+--------------------+---------------------------------------------------------------------------+
| loadexcel | le | Load translated lines of the given language from a excel file. |
+--------------------+---------------------------------------------------------------------------+
| dumpexcel | de | Dump translations of the given language to a excel file. |
+--------------------+---------------------------------------------------------------------------+
| inspect | Inspect each translated line to find missing vars or tags, |
| | then save these error lines to a excel file. You can use the |
| | updateexcel command to update translations after you fix them. |
+--------------------+---------------------------------------------------------------------------+
| updateexcel | ue | Update translations of the given language from a excel file. |
+--------------------+---------------------------------------------------------------------------+
| savejson | sj | Save untranslated lines of the given language to a json file. |
+--------------------+---------------------------------------------------------------------------+
| loadjson | lj | Load translated lines of the given language from a json file. |
+--------------------+---------------------------------------------------------------------------+
| help | h | Print name and description of each command. |
+--------------------+---------------------------------------------------------------------------+
| quit | q | Quit the program. |
+--------------------+---------------------------------------------------------------------------+
| reconfig | Reload config from disk. It takes effect for most config items. |
+--------------------+---------------------------------------------------------------------------+
| about | About me. |
+--------------------+---------------------------------------------------------------------------+
| cls | Clean screen. |
+--------------------+---------------------------------------------------------------------------+
You should know how to translate RenPy games (How to translate?). And, as you are familiar with using this tool, you can translate RenPy games quickly.
This tool supports to extract Voice statements or others, but the feature is turned off. It only extracts Say statements by default.
# game/script_21_1320.rpy:8
translate chinese scene_01_5f0ee2360:
# voice "path/to/file"
# a "text"
voice "path/to/file"
a "translated text"
For the above translation rpy, only a "translated text"
will be extracted. To enable extracting voice "path/to/file"
, please set index.say_only
as False
in config.yaml.
You can download a packaged exe file for Windows to run this tool without installation of Python, see Release. To use AI translation, the installation for Python is still needed.
Note
Yon can get an main.exe in Release to run this tool. It only works on Windows OS.
After installing python 3.8, use pip to install the dependencies:
pip install -r requirements_full.txt
Once installed, launch the main program:
python main.py
After starting the main program, run the following command in the opened console:
n D:\games\renpy_game_demo -n my_game
-
D:\games\renpy_game_demo
is the root dir of your RenPy game. -
-n my_game
is optional,which enables you to take a nickname for the TranslationIndex. You can use this nickname to specify the TranslationIndex instead of an index when running a command. If no nickname is specified, it will be randomly generated.In addition, you can define an optional tag by providing the
-t
arg (e.g.,-t 1.0
). If no tag is provided, the default one isNone
. -
n
is short name ofnew
command. We have defined many short names for common commands. And you can run the commandhelp -u
to print the details of all commands (including their short names).[!NOTE]
If the path of RenPy game contains spaces, please use double quotes (or single quotes) to enclose the path. For example:new "D:\games\renpy game_demo" -n my_game
Then, enter ls
command to see the TranslationIndex we created:
ls
It outputs like:
Note that: Translation Stats list translated/untranslated lines of dialogue and string for each language.
+-------+---------------+-------------------+------------------+-----------------------------------------------------+
| Index | Nickname:tag | Translation Stats | Injection state | Game info |
+-------+---------------+-------------------+------------------+-----------------------------------------------------+
| 1 | my_game:None | | Base True | renpy_game_demo-V0.1, Ren'Py 7.4.11.2266 |
| | | | | D:\games\renpy_game_demo |
+-------+---------------+-------------------+------------------+-----------------------------------------------------+
Note that the Base True
in Injection state
means that we have successfully identified and injected the game.
Note
Before running this command, please make sure that all files are extracted from rpa files in the game dir (by useing rpatool or UnRPA). And all rpyc file have converted into rpy files (Otherwise, most of the translations cannot be scanned. You can use unrpyc). This tool integrates unrpa and unrypc: UnRen.
If you find files whose name end with .rpa
in your your_game_root
/game
dir (e.g, D:\games\renpy_game_demo\game
), or there exists only rpyc files without corresponding rpy files which have same filenames, you should unren the game.
- Download
UnRen-forall.bat
from UnRen Releases: Unzip it, you will get aUnRen-forall.bat
, then put it into your game root dir: - Click it to run, and input: Enter key, 8, Enter key: Then, input: y: Just wait to be done, and you can close it:
Next, run the command:
i my_game -l schinese
my_game
specifies the nickname of the TranslationIndex to import into, which can also use the Index:1
, or a combination of nickname and tag:my_game:None
.-l schinese
names the translations asschinese
.- This command will read both translated and untranslated texts in
D:\games\renpy_game_demo\game\tl\schinese
.
Enter ls
command to see translations we imported:
ls
It outputs like:
Note that: Translation Stats list translated/untranslated lines of dialogue and string for each language.
+-------+---------------+-----------------------------------------+------------------+-----------------------------------------------------+
| Index | Nickname:tag | Translation Stats | Injection state | Game info |
+-------+---------------+-----------------------------------------+------------------+-----------------------------------------------------+
| 1 | my_game:None | Language Dialogue String Sum | Base True | renpy_game_demo-V0.1, Ren'Py 7.4.11.2266 |
| | | schinese 0/940 0/384 1324 | | D:\games\renpy_game_demo |
+-------+---------------+-----------------------------------------+------------------+-----------------------------------------------------+
For convenience, we use savehtml
and loadhtml
to perform quick translation. Other Translate commands are available at: Web Translation, AI Translation, ⚡Fast translating⚡ with saveexcel
and loadexcel
, Use Uliontse-translators
Now let's translate with savehtml
and loadhtml
command:
sh 1 -l schinese
It outputs like:
1320 untranslated lines are saved to ./projz\html\my_game_None_schinese.html.
If you think that the number of lines is too large, you can specify --limit {max_num}
to set the max number of lines to save.
Then, open the HTML file with Chrome or Microsoft Edge. Right click to open context menu, and select the translation option to translate this page. After translating, please press Ctrl+S to save and overwrite the original html file. For more instructions, please refer to ⚡Fast translating⚡ with savehtml
and loadhtml
.
Next, use loadhtml
command to update translations:
lh 1 -l schinese
It outputs like:
...
...
Find 1229 translated lines, and discord 91 lines
schinese: 854 updated dialogue translations, 375 updated string translations. [use:1229, discord:0, total:1229]
Enter ls
command to see translations we updated:
Note that: Translation Stats list translated/untranslated lines of dialogue and string for each language.
+-------+---------------+-----------------------------------------+------------------+-----------------------------------------------------+
| Index | Nickname:tag | Translation Stats | Injection state | Game info |
+-------+---------------+-----------------------------------------+------------------+-----------------------------------------------------+
| 1 | my_game:None | Language Dialogue String Sum | Base True | renpy_game_demo-V0.1, Ren'Py 7.4.11.2266 |
| | | schinese 856/84 377/7 1324 | | D:\games\renpy_game_demo |
+-------+---------------+-----------------------------------------+------------------+-----------------------------------------------------+
⏱What's the fastest translation commands?
Generally speaking, the ranking of translation speed (from fastest to slowest) is:
saveexcel and loadexcel (semi-automatically): Manually upload the excel file to Google Translate, and save the translated file to overwrite the original one.
savehtml and loadexcel (semi-automatically): Use the translation function from Microsoft Edge or Chrome (You need to scroll the page from top to bottom to make all text get translated), and save the translated file to overwrite the original one.
Uliontse/translators (automatically):
translate {index_or_name} -t ts -n bing -l {lang}
Web translation (automatically):
translate 1 -t web -n google -l {lang}
Use the automation tool to enter text into the input box in the translation website, and automatically extract the translation result.AI Translation (automatically):
translate 1 -t ai -n mbart50 -l {lang}
Use deep network models to translate (with GPU resources).It's still difficult to assess the translation quality of each translation command.
Since we just send the raw text to the translator, the translation result may contain some content that cause a runtime error when playing game. For example, the following raw text:
Today is [day].
may be translated (into Chinese) as:
今天是[天]。
There exists an obvious error that the variable [day]
is translated incorrectly as [天]
. As a result, you will receive a KeyError when playing.
There also some other kinds of error in translation result that raise a runtime error when playing:
1. You can set it to a {size=30}fixed size{/size}.
->你可以将其设置为{大小=30}固定大小{/大小}。
Error: `{大小=30}` and `{/大小}` should be `{size=30}` and `{/size}`, respectively.
2. I have 100%% confidence.
->我有100%的信心。
Error: `100%` should be `100%%`.
...
To find these potential error, we can use inspect
command to export these errors to an Excel file by:
inspect 1 -l schinese
Then, open it to correct these errors manually in the new_text
column:
The column message
show the missing tags\variables\escape chars in new_text
compared to the raw_text
.
After fixing them, use the updateexcel
command to update translations:
ue 1 -l schinese
Use generate
command to generate translation rpy files to the game:
g 1 -l schinese
It outputs like:
...
...
schinese: dialogue translation: using 856 and missing 84, string translation: using 377 and missing 7
Note that, if there exists rpy files in game/tl/{lang}
, existing translations in these files will not be overwritten. generate
command only append translations that don't exist in the game by default. If you want to apply all TranslationIndex's translated texts that exist in these rpy files, please append the -f
option to generate
command. That will delete all rpy/rpyc files in game/tl/{lang}
.
In order to display translated texts correctly after changing the language, we have provided three fonts (download links can be found in resources/fonts/readme.txt
):
projz_renpy-translator/
|–– resources/
|–– fonts
–– DejaVuSans.ttf
–– SourceHanSansLite.ttf
–– Roboto-Light.ttf
–– readme.txt
You can manually place custom fonts in resources/fonts
dir (please pay attention to the copyright issue of fonts). And add font paths in config.yaml, so that the program will copy these fonts to the game dir. You can find these added font configs in I18N interface.
Run inject
command to inject the I18N plugin (which enables you to chainge language or font):
ij 1 -t I18n
Enter ls
command to see injection states:
Note that: Translation Stats list translated/untranslated lines of dialogue and string for each language.
+-------+---------------+-----------------------------------------+------------------+-----------------------------------------------------+
| Index | Nickname:tag | Translation Stats | Injection state | Game info |
+-------+---------------+-----------------------------------------+------------------+-----------------------------------------------------+
| 1 | my_game:None | Language Dialogue String Sum | Base True | renpy_game_demo-V0.1, Ren'Py 7.4.11.2266 |
| | | schinese 856/84 377/7 1324 | I18n True | D:\games\renpy_game_demo |
+-------+---------------+-----------------------------------------+------------------+-----------------------------------------------------+
Finally, open the RenPy game and enjoy it. You can open the location of game by launch
command (o 1
), or launch it by open
command (launch 1
).
You can show the I18N menu by using the shortcut key "Ctrl+i", or click the I18N button in game's preference menu. (To show the I18N button, the "screens.rpyc" should be converted into "screens.rpy" to inject its code.):
Note
If there exists an error while launching the game or I18n plugin, you can use ij 1 -t I18n -u
to undo injecting.
Or you can try a compatible version of I18n plugin, by coping the content of resources/codes/projz_i18n_inject_4oldversion.rpy to overwrite resources/codes/projz_i18n_inject.rpy, then redo injecting ij 1 -t I18n
.
Tip
You can config languages and fonts in config.yaml for I18N plugin. The final available languages generated by inject
command is determined by languages shared between lang_map
in config.yaml and dirs in game/tl
(except None
).
You can config fonts to fonts
in config.yaml.
If there exists the font config in game/tl/{lang}/style.rpy
, it will disable our font setting because of its higher priority. That font config may like:
translate schinese python:
gui.system_font = gui.main_font = gui.text_font = gui.name_text_font = gui.interface_text_font = gui.button_text_font = gui.choice_button_text_font = "SourceHanSansLite.ttf"
If existing above configs, you can't change fonts in I18N menu.
Changes of configs of Developer Mode and Debug Console will apply after reloading the game. Shortcut keys of Debug Console (Shift+O) and Reload Game (Shift+R) work only when Developer Mode is set to True.
Enter help
command, and it will print the description and usage of all commands. To see all args of a command, please append a -h
option to the command:
new -h
This will print the detailed usage of new
command:
🍻To the end🍻
We're glad to you integrate your translation implementation into our tool, or help us translate the documentation.
- To apply changes in config.yaml, use
reconfig
command. It takes effect for most config items. - If you want to ignore the translations of certain rpy files when importing and generating translations, please add these files to
index.ignore
in config.yaml. Note that, the path splitter in Windows OS is "\", that means that if you want to ignore translations ofscript/demo.rpy
, you should rewrite its path toscript\demo.rpy
. If there exists space in the path, just keep it. - The tool will automatically download models in local dir if
translator.ai.model_path
is empty in config.yaml. - You can use
de {index_or_name} -l {lang}
to export translation data (including translated and untranslated texts) of a given TranslationIndex to an Excel file, then update translations (ue {index_or_name} -l {lang}
) from it after you modify them. In this way, you can alter translations or translate them manually. - You can strip style tags before translating by setting
index.strip_tag
toTrue
in config.yaml. - You can mark all untranslated texts as translated ones by
mark
command:mark {index_or_name} -l {lang}
- You can rename a name of translations by
rename
command:rename {index_or_name} -l {lang} -t {new_lang}
, where{new_lang}
is new one. - To merge translations from another TranslationIndex into current TranslationIndex, use
merge
command:merge {index_or_name} -l {lang} -s {source_index}
, where{source_index}
is the source index to merge from. This enables you to use translations of old game to that of new game when new one is released.
By saving translations to an Excel file, use translation website to translate. Then update translations from the translated file.
-
Run the command
se {index_or_name} -l {lang}
to export untranslated texts to an Excel file. Upload the file to any translation website that supports document translation: -
Wait until it is finished, then download it and overwrite the original file:
-
Run the command
le {index_or_name} -l {lang}
to update translations in TranslationIndex.
😕Translation website doesn't support uploading Excel files?
You can paste content of the generated Excel file into a doc file, then upload it. After completion, copy content from translated doc file to the Excel file.
By saving translations to an HTML file, use Microsoft Edge or Chrome to translate. Then update translations from the translated file.
-
Run the command
sh {index_or_name} -l {lang}
to export untranslated texts to an HTML file. Open it with Microsoft Edge or Chrome. -
Click translation option in context menu or at address bar:
-
Scroll the page from top to bottom to get all the text translated, then save the file and overwrite the original HTML file.
-
Run the command
lh {index_or_name} -l {lang}
to update translations in TranslationIndex.
Download and install Chrome浏览器. Find your Chrome version in Settings->About Chrome, then download the corresponding Chrome driver from following links:
Download the file whose name contains "win64"/"win32" (It depends on your Windows system processor architecture. "win64" is common for most modern PCs), and unzip it to a dir.
Then config the path translator.web.chrome_driver_path
for the Chrome driver
in config.yaml:
projz:
translator:
web:
chrome_driver_path: 'D:\Users\Surface Book2\Downloads\chromedriver_win32\chromedriver.exe'
- Run the command
t {index_or_name} -t web -n google -l {lang}
- Wait until the page displays, and set your translation target manually:
- Wait for the prompt in console, and enter
Y
ory
(the others to quit) to continue. Then, the tool starts automatically translating.
If you want to use AI translation with CPU, please skip this step. These following instructions guide you to install suitable Pytorch that compatible with your NVIDIA GPU. It suggests that your GPU memory is not less than 4 GB.
-
Open a CMD, and run the following command to see your CUDA version:
nvidia-smi
It may output like:
+-----------------------------------------------------------------------------+ | NVIDIA-SMI 517.48 Driver Version: 517.48 CUDA Version: 11.7 | |-------------------------------+----------------------+----------------------+ | GPU Name TCC/WDDM | Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |===============================+======================+======================| | 0 NVIDIA GeForce ... WDDM | 00000000:02:00.0 Off | N/A | | N/A 33C P0 21W / N/A | 0MiB / 6144MiB | 1% Default | | | | N/A | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=============================================================================| | No running processes found | +-----------------------------------------------------------------------------+
It is shown that the CUDA version is 11.7. If you have run the command
pip install -r requirements_full.txt
before, you can skip the following step and goto Get started part. That version is what we use inrequirements_full.txt
. -
Next, uninstall some libraries:
pip uninstall torch torchaudio torchvision transformers
Goto the Pytorch, and follow its instructions to install the Pytorch that matches your CUDA. The following content is what I found:
# For Linux and Windows # ROCM 5.4.2 (Linux only) pip install torch==2.0.1+rocm5.4.2 torchvision==0.15.2+rocm5.4.2 torchaudio==2.0.2 --index-url https://download.pytorch.org/whl/rocm5.4.2 # CUDA 11.7 pip install torch==2.0.1+cu117 torchvision==0.15.2+cu117 torchaudio==2.0.2 --index-url https://download.pytorch.org/whl/cu117 # CUDA 11.8 pip install torch==2.0.1+cu118 torchvision==0.15.2+cu118 torchaudio==2.0.2 --index-url https://download.pytorch.org/whl/cu118 # CPU only pip install torch==2.0.1+cpu torchvision==0.15.2+cpu torchaudio==2.0.2 --index-url https://download.pytorch.org/whl/cpu
-
Reinstall the appropriate "transformers" library:
pip install transformers
If you can access huggingface page, it means that this tool can download models without any problem. You can set the path translator.web.chrome_driver_path
to empty in config.yaml, which lets this tool download model automatically:
projz:
translator:
ai:
model_path: ''
And just goto Get started part.
If you want to specify the location of downloaded models, or have some problems during using AI translation like:
The following instructions guide you to download models manually:
-
Suppose your models is saved in:
'D:\Download\New36\save_models'
. There are some links to download them: -
Choose a model you want, and create a dir that has same name with that of the model (
m2m100
,mbart50
,nllb200
) inD:\Download\New36\save_models
. I choose them2m100
model here, so I have the dirD:\Download\New36\save_models\m2m100
.Download all files in this page except
rust_model.ot
: -
Once finished downloading, config the root dir in config.yaml:
projz: translator: ai: model_path: 'D:\Download\New36\save_models'
-
Run the command:
t {index_or_name} -t ai -n {model_name} -l {lang} -b 4
-n
specifies the model to use. Available models are :m2m100
,mbart50
,nllb200
. I use them2m100
model here.-b
specifies the batch size during translating. It determines how many lines of untranslated text feed into the model. The bigger the value is, the more GPU memory it uses.
-
Set the translation target. If you want to translate text from English into Chinese, just enter their indexes:
19 109
-
Then, the tool starts automatically translating.
-
Run the command:
t {index_or_name} -t ts -n {API_name} -l {lang}
-n
specifies the API service to use. You can run the commandt -t ts -h
to show available API services. Default asbing
.
-
Set the translation target. This is similar to step 2 in AI translation.
-
Then, the tool starts automatically translating.
Note that, args of translate_text
and preaccelerate
method using in this command, can be configed at translator.translators
in config.yaml. Learn more: UlionTse/translators
Config your OpenAI Endpoint in config.yaml:
You can config your chat.completions.model
, init.api_key
, and init.base_url
.
The {target_lang}
in the prompt is the language to translate into, which is determined at run time.
The {text}
in the prompt is the text to translate when translating.
open_ai:
target_lang: 'Chinese'
user_role: &user_role 'user'
max_turns: 8 # Specify the maximum number of rounds for the conversation.
langs: [...]
models: [...]
# Template Args
# Args for initializing OpenAI() client
init:
base_url: http://localhost:11434/v1/
api_key: 'ollama'
chat:
# Your client should have an endpoint whose url ends with "chat/completions". E.g., http://localhost:11434/v1/chat/completions
# Args for client.chat.completions.create(), see https://platform.openai.com/docs/api-reference/chat/create
completions:
# temperature: 0.2
# top_p: 0.1
stream: false
model: "qwen:0.5b"
messages:
-
role: "system"
content: "You are a professional translator. You are now required to translate the text given by the user into {target_lang} based on the context of the chat. Content enclosed in square brackets (For example, [lisa_alias], [day]) does not need to be translated. NO EXPLANATION is needed for the translation result."
# content: "你是一个专业的翻译家。现在要求你根据聊天上下文信息把用户给定的文本翻译为{target_lang}。以方括号括起来的内容(例如: [lisa_alias], [day])不需要翻译。不需要对翻译结果做任何解释。"
-
role: *user_role
content: "{text}"
t {index_or_name} -t openai -n {API_name} -l {lang}
Tip
We strongly recommend that using the 'llm_translate' command instead of the above translation command. To use llm_translate
command:
lt {index or name} -l {lang} -m qwen:0.5b -t Chinese
or
lt {index or name} -l {lang} -a
Select the "CloseAI" in provider list in UI.
You can integrate your translation API easily to this tool. Create a py file in translator, and let your translation class inherits one of template classes. CachedTranslatorTemplate
class has a translation buffer which allows to write translations into TranslationIndex when reaching a certain number. The cache size can be configed by translator.write_cache_size
in config.yaml. TranslatorTemplate
class provides basic implementation that writes all translations into TranslationIndex at once.
from argparse import ArgumentParser
from translator.base import CachedTranslatorTemplate
from command.translation.base import register_cmd_translator
from typing import List, Tuple
from config.base import ProjzConfig
# The pipeline of a translator. The following code provide a simple version of DlTranslator
# 1. The users enter: translate 1 -l chinese -t ai --name mbart50
# 2. Create a new instance of DlTranslator, then call register_args method.(Note that, your class should use a non-parameter constructor)
# 3. If there exists '-h' or '--help' in user input, print help and goto 7.
# 4. Call do_init method (Put your init code in the method. The passed args and config are ready at this moment).
# If do_init() returned False, goto 7.
# 5. Call invoke method (The Base class CachedTranslatorTemplate or TranslatorTemplate has implemented it.)
# 6. The default implementation of invoke calls translate_batch method. And the default implementation of translate_batch calls translate method within a for-loop.
# 7.Done
class DlTranslator(CachedTranslatorTemplate):
def register_args(self, parser: ArgumentParser):
super().register_args(parser)
# Register your args
# Note that, any init code shouldn't place here as user may want to print help instead of using it.
# You should put your init code in do_init()
parser.add_argument('-n', '--name', choices=['m2m100', 'mbart50', 'nllb200'], default='mbart50',
help='The name of deep learning translation model.')
def do_init(self, args, config: ProjzConfig):
super().do_init(args, config)
# The method will be called when the user decides to use this translation API.
# Put your init code here. The rgs and config are ready.
self._model_name = args.name
self._model_path = config['translator']['ai']['model_path']
self._load_model()
return True # Return True if everything is OK.
def translate(self, text: str):
# Your implementation for translating.
# The method take a text and return a translated text.
return self.mt.translate(text, self._source, self._source, batch_size=1, verbose=True)
def translate_batch(self, texts: List[str]):
# If your translation API supports to translate a batch of texts,
# you can implement this method. The length of `texts` and that of returned texts should be the same.
# The default implementation will call translate method within a for-loop if you don't override this method.
# CachedTranslatorTemplate class writes translations into TranslationIndex after each call of translate_batch.
# The max length of texts can be configed by translator.write_cache_size in config.yaml.
return self.mt.translate(texts, self._source, self._source, batch_size=self._batch_size, verbose=True)
# Register your translation API to translation command
# User can run the command: translate 1 -l chinese -t ai --name mbart50
# where -t ai is the name of your translation API you register
# Note that, DlTranslator use a non-parameter constructor.
# Don't forget to add the call of __init__ of super class to your non-parameter constructor if you have it.
register_cmd_translator('ai', DlTranslator)
Finally, import your translation API in translator/__init __.py:
import logging
import translator.base
try:
import translator.web
except Exception as e:
print(f'error: {e}')
logging.exception(e)
try:
# You should use the try-except block to wrap your import statement.
# It allows users to launch the main program even if there exists missing libs in user's environment.
import translator.ai
except Exception as e:
print(f'error: {e}')
logging.exception(e)
To see complete implementation of DlTranslator, please see translator/ai/impl.py.
- 799190761
- ansan
If you find your name missed in this list, please accept my apologies and email me to add it.
- Add English document
- GUI support
- Text check when translating
The codes or libs we use or refer to:
- Previous code of Web translation: Maooookai(Mirage), DrDRR
- AI translation: dl-translate, MIT License
- UlionTse/translators, GPL-3.0 License
- Pre-translated RPY file: RenPy, MIT License for these rpy files
- resources/codes/projz_injection.py: RenPy, MIT License for the code file
- UI: PyQt5, it contains dual licenses: the GNU GPL v3 and the Riverbank Commercial License. See here.
- UI theme: Qt-Material, BSD-2-Clause license
- Other python libs:requirements_full.txt