Skip to content

Commit 3db26d2

Browse files
committed
πŸ§‘β€πŸ’» Use LLM for language translation
1 parent 18b5301 commit 3db26d2

File tree

1 file changed

+51
-1
lines changed

1 file changed

+51
-1
lines changed

β€Žbuildroot/share/scripts/languageExport.pyβ€Ž

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,14 @@
1010

1111
import re
1212
from pathlib import Path
13-
from sys import argv
13+
from sys import argv, exit
1414
from languageUtil import namebyid
1515

1616
LANGHOME = "Marlin/src/lcd/language"
1717

1818
# Write multiple sheets if true, otherwise write one giant sheet
1919
MULTISHEET = '--single' not in argv[1:]
20+
DO_TRANSLATE = '--translate' in argv[1:]
2021
OUTDIR = Path('out-csv')
2122

2223
# Check for the path to the language files
@@ -121,6 +122,55 @@ def write_csv_lang(f, strings, name):
121122
f.write(',')
122123
if name in strings['tall']: f.write('"%s"' % strings['tall'][name])
123124

125+
if DO_TRANSLATE:
126+
127+
import ollama
128+
129+
OLLAMA_MODEL = ("gpt-oss:20b", "llama3.3")[0]
130+
system_prompt_text = """You are an expert in language translation in the context of 3D printing.
131+
You will be given a list of existing translations and will be asked to provide a new translation in the given language.
132+
Your translations must be no more than 18 characters long! Use common abbreviations whenever necessary.
133+
Assume that named substitutions such as (MACHINE_NAME) are short strings for the purpose of character counting.
134+
For each translation requested, respond only with the translated string, no introduction, explanation, or assessment.
135+
This clean output will be perfect for our use case.
136+
"""
137+
SYSTEM_PROMPT = [{ 'role': 'system', 'content': system_prompt_text }]
138+
139+
# Send a prompt to Ollama
140+
def prompt_with_ollama(prompt:str):
141+
msg = [{ 'role': 'user', 'content': prompt }]
142+
response = ollama.chat(model=OLLAMA_MODEL, messages=SYSTEM_PROMPT + msg, stream=False)
143+
return response['message']['content']
144+
145+
# For each named string find all existing and needed translations
146+
for name in names.keys():
147+
done = {}
148+
todo = []
149+
for lang in langcodes:
150+
lname = f"{namebyid(lang)} ({lang})"
151+
strings = language_strings[lang]
152+
if name in strings['narrow']:
153+
done[lang] = strings['narrow'][name]
154+
else:
155+
todo += [lang]
156+
157+
# For each untranslated language, fill in a translation
158+
for lang in todo:
159+
# Show existing translations to the LLM and ask for one more
160+
prompt = [ f"Please translate the following string into {namebyid(lang)} ({lang})." ]
161+
if lang == "fr_na":
162+
prompt += [ "(Substitute plain unaccented ASCII characters for accented characters in the output.)" ]
163+
prompt += [ "Here are the existing translations:" ]
164+
for lang in done.keys():
165+
prompt += [ f"- {lang} {namebyid(lang)}: \"{done[lang]}\"" ]
166+
prompt = '\n'.join(prompt)
167+
#print(f"Prompt: {prompt}")
168+
newstring = prompt_with_ollama(prompt)
169+
print(f"{name} ({lang}) = \"{newstring}\"")
170+
done[lang] = newstring
171+
if not 'narrow' in language_strings[lang]: language_strings[lang]['narrow'] = {}
172+
language_strings[lang]['narrow'][name] = newstring
173+
124174
if MULTISHEET:
125175
#
126176
# Export a separate sheet for each language

0 commit comments

Comments
Β (0)