Skip to content

Commit fcd1cbf

Browse files
committed
Enhance Hungarian normalisation: add new entries, improve force change handling, and implement Roman numeral conversion
1 parent 38b013c commit fcd1cbf

File tree

4 files changed

+221
-68
lines changed

4 files changed

+221
-68
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Magyar szüvegnormalizáló az F5-TTS kiejtésének javításához.

src/f5_tts/infer/normalisers/hun/changes.csv

Lines changed: 105 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
AI, é áj
2+
MI, emi
3+
PDA, pédéa
14
GPS, dzipiesz
25
chips, csipsz
36
Kyle, kájl
@@ -452,4 +455,105 @@ Hannibal, Hannibál
452455
Eugen, Ögen
453456
Colonna, Kolonna
454457
Orsini, Orszíni
455-
campagna, kampannya
458+
campagna, kampannya
459+
Mozart, Mócárt
460+
Travis, Travísz
461+
Parker, Parkőr
462+
Gabby, Gábí
463+
Nicholas, Niklesz
464+
Sparks, Szparksz
465+
Beaufort, Bófor
466+
grizzly, gízli
467+
Shackleford, Saklefőr
468+
Banks, Bénksz
469+
Carteret, Kardöret
470+
hospital, hászpital
471+
Matt, Met
472+
Moby, Móbí
473+
Joe, Dzsó
474+
Laird, Lérd
475+
Megan, Megön
476+
Allison, Áliszn
477+
Braves, Brévsz
478+
Dodgers, Dádzsörsz
479+
Liz, Líz
480+
Vail, Véll
481+
Tina, Tiná
482+
Henry, Henrí
483+
Wake, Vék
484+
Forest, Fóreszt
485+
Duke, Dúk
486+
Colorado, Kolorádó
487+
Monica, Móniká
488+
Olivia, Olívia
489+
Oliv, Ollev
490+
Leslie, Lezlí
491+
Gwen, Gven
492+
Clue, Klú
493+
Josie, Dzsózi
494+
Stephanie, Sztefeni
495+
Chapel, Csápl
496+
Hill, Hil
497+
Rolling, Róllin
498+
Stones, Sztónz
499+
Tattoo, Tátú
500+
Yout,
501+
Nobby, Nábí
502+
Virginia, Vördzsínia
503+
wake, Vék
504+
fair, fer
505+
Morehead, Mórhed
506+
City, Szidí
507+
Kevin, Kevön
508+
Adrian, Édrien
509+
Melton, Meltön
510+
New York, Nyújork
511+
Los Angeles, lászendzselesz
512+
Chicago, Sikágó
513+
Houston, Hjúsztn
514+
Phoenix, Főnix
515+
Philadelphia, Filadelfia
516+
San Antonio, szen antonió
517+
San Diego, szen diégo
518+
Dallas, dálesz
519+
San Jose, szenhózé
520+
Austin, osztin
521+
Jacksonville, dzsekszonvil
522+
Fort Worth, fortvörsz
523+
Columbus, kolumbusz
524+
Charlotte, sárlot
525+
San Francisco, szenfrensziszkó
526+
Indianapolis, indianapolisz
527+
Seattle, szietl
528+
Denver, denvör
529+
Washington, vasington
530+
Boston, bosztön
531+
El Paso, elpászó
532+
Nashville, nesvil
533+
Detroit, ditroit
534+
Oklahoma City, oklahomasziti
535+
Portland, portlend
536+
Las Vegas, lászvégász
537+
Memphis, memfisz
538+
Louisville, lúivill
539+
Baltimore, baltimór
540+
Milwaukee, milvóki
541+
Albuquerque, elbökörki
542+
Tucson, túszon
543+
Fresno, freznó
544+
Mesa, méza
545+
Sacramento, szakramento
546+
Atlanta, etlentá
547+
Kansas City, kenzeszsziti
548+
Colorado, kolorádó
549+
Texas, tekszasz
550+
Florida, florida
551+
Georgia, dzsordzsa
552+
Ohio, ohájó
553+
Nevada, nevada
554+
Arizona, arizóna
555+
Tennessee, teneszi
556+
California, kalifornia
557+
New Jersey, nyúdzsörzi
558+
Illinois, illinoj
559+
Michigan, misigen
Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
%, százalék
2-
ninjutsu, nindzsucu
3-
tweet, tvít
4-
chips, csipsz
5-
ly, j
1+
%, százalék, 1, 1
2+
ninjutsu, nindzsucu, 0, 0
3+
tweet, tvít, 0, 0
4+
chips, csipsz, 0, 0
5+
w, v, 0, 0
6+
ly, j, 0, 0

src/f5_tts/infer/normalisers/hun/normaliser.py

Lines changed: 109 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,66 @@
66
# Határozzuk meg a normaliser.py könyvtárát
77
base_dir = os.path.dirname(os.path.abspath(__file__))
88

9+
# Római számokat arab számmá alakító segédfüggvény
10+
def roman_to_int(s):
11+
roman_map = {'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000}
12+
total = 0
13+
prev = 0
14+
for char in reversed(s):
15+
val = roman_map[char]
16+
if val < prev:
17+
total -= val
18+
else:
19+
total += val
20+
prev = val
21+
return total
22+
23+
def replace_roman_numerals(text):
24+
"""
25+
Minden olyan tokent, ami csak római számból áll (I,V,X,L,C,D,M),
26+
opcionálisan egy végponttal, arab számmá alakítjuk.
27+
Pl. 'VI' -> '6', 'IX.' -> '9.'
28+
"""
29+
pattern = re.compile(r'\b([MDCLXVI]+)(\.)?\b')
30+
def repl(m):
31+
roman, dot = m.group(1), m.group(2) or ''
32+
# csak akkor alakítjuk, ha érvényes római számként értelmezhető
33+
try:
34+
arab = roman_to_int(roman)
35+
except KeyError:
36+
return m.group(0)
37+
return f"{arab}{dot}"
38+
return pattern.sub(repl, text)
39+
940
def load_force_changes(filename="force_changes.csv"):
10-
# A fájl elérési útja a base_dir könyvtárhoz képest
41+
"""
42+
A force_changes.csv most négy oszlopos:
43+
key, value, spaces_before, spaces_after
44+
"""
1145
file_path = os.path.join(base_dir, filename)
1246
force_changes = {}
1347
with open(file_path, encoding='utf-8') as csvfile:
1448
reader = csv.reader(csvfile)
1549
for row in reader:
16-
if row:
17-
key, value = row
18-
force_changes[key.strip()] = value.strip()
50+
if not row:
51+
continue
52+
key, value, spaces_before, spaces_after = row
53+
key = key.strip()
54+
value = value.strip()
55+
# számokra castelünk
56+
before = int(spaces_before.strip())
57+
after = int(spaces_after.strip())
58+
force_changes[key] = (value, before, after)
1959
return force_changes
2060

2161
def apply_force_changes(text, force_changes):
22-
# Fix cserék alkalmazása a szövegre
23-
for key, value in force_changes.items():
24-
text = text.replace(key, f' {value} ')
62+
"""
63+
A CSV-ben megadott szócsere után annyi szóközt teszünk
64+
előre-utólag, amennyit a 3–4. oszlopban látunk.
65+
"""
66+
for key, (value, before, after) in force_changes.items():
67+
replacement = ' ' * before + value + ' ' * after
68+
text = text.replace(key, replacement)
2569
return text
2670

2771
def load_changes(filename="changes.csv"):
@@ -43,33 +87,19 @@ def apply_changes(text, changes):
4387
text = re.sub(pattern, value, text, flags=re.IGNORECASE)
4488
return text
4589

46-
ordinals = {
47-
1: 'első',
48-
2: 'második',
49-
3: 'harmadik',
50-
4: 'negyedik',
51-
5: 'ötödik',
52-
6: 'hatodik',
53-
7: 'hetedik',
54-
8: 'nyolcadik',
55-
9: 'kilencedik',
56-
10: 'tizedik',
57-
# További sorszámok hozzáadása szükség szerint
58-
}
5990

60-
def replace_ordinals(text, ordinals):
61-
# Sorszámok átírása, kivéve ha a mondat végén vannak
62-
def repl(match):
63-
num = int(match.group(1))
64-
start, end = match.span()
65-
following_text = text[end:]
66-
if re.match(r'^\s*$', following_text) or re.match(r'^\s*[\.!\?]', following_text):
67-
return match.group(0)
68-
ordinal_word = ordinals.get(num, num2words(num, to='ordinal', lang='hu'))
69-
return ordinal_word
70-
pattern = r'(\d+)\.(?![\s]*$|[\s]*[\.!\?])'
71-
text = re.sub(pattern, repl, text)
72-
return text
91+
def replace_ordinals(text):
92+
"""
93+
Bármilyen nagyságú arab számból álló sorszámot (pl. 1233.)
94+
átír num2words segítségével magyar ordítóvá.
95+
A patrón biztosítja, hogy a mondatvégén álló számot ponttal ne bántsa.
96+
"""
97+
pattern = re.compile(r'\b(\d+)\.(?!\s*$|\s*[\.!\?])')
98+
def repl(m):
99+
num = int(m.group(1))
100+
# a num2words kész ordító formát ad vissza, pl. 'ezerkettőszázharmincháromadik'
101+
return num2words(num, to='ordinal', lang='hu')
102+
return pattern.sub(repl, text)
73103

74104
months = {
75105
'jan.': 'január',
@@ -142,52 +172,67 @@ def day_to_text(day):
142172
return day_words.get(day, num2words(day, lang='hu') + 'ika')
143173

144174
def replace_dates(text):
145-
# Dátumok felismerése és átírása
175+
# 0. Külön kezeli az "N-án" vagy "N-én" formátumot
176+
pattern0 = re.compile(r'\b(\d{1,2})-(án|én)\b')
177+
def repl0(m):
178+
day = int(m.group(1))
179+
suffix = m.group(2) # 'án' vagy 'én'
180+
ordinal = num2words(day, to='ordinal', lang='hu')
181+
return ordinal + suffix
182+
text = pattern0.sub(repl0, text)
183+
184+
# --- először mindegyik dátumformátum, mint eddig ---
146185
month_abbrs = '|'.join(re.escape(k) for k in months.keys())
147186

148-
# Év.Hónap.Nap formátum (2015.10.23.)
149-
pattern1 = r'(\d{4})\.(\d{1,2})\.(\d{1,2})\.'
150-
def repl1(match):
151-
year = int(match.group(1))
152-
month = int(match.group(2))
153-
day = int(match.group(3))
187+
# 1. Év.Hónap.Nap formátum (2015.10.23.)
188+
pattern1 = re.compile(r'(\d{4})\.(\d{1,2})\.(\d{1,2})\.')
189+
def repl1(m):
190+
year, month, day = map(int, m.groups())
154191
year_text = num2words(year, lang='hu')
155192
month_text = months_numbers.get(month, '')
156193
day_text = day_to_text(day)
157194
return f'{year_text} {month_text} {day_text}'
158-
text = re.sub(pattern1, repl1, text)
195+
text = pattern1.sub(repl1, text)
159196

160-
# Év.HónapRöv.Nap formátum (2015.okt.23.)
161-
pattern2 = r'(\d{4})\.(' + month_abbrs + r')(\d{1,2})\.'
162-
def repl2(match):
163-
year = int(match.group(1))
164-
month_abbr = match.group(2)
165-
day = int(match.group(3))
197+
# 2. Év.HónapRöv.Nap formátum (2015.okt.23.)
198+
pattern2 = re.compile(r'(\d{4})\.(' + month_abbrs + r')(\d{1,2})\.')
199+
def repl2(m):
200+
year = int(m.group(1))
201+
month_abbr = m.group(2)
202+
day = int(m.group(3))
166203
year_text = num2words(year, lang='hu')
167204
month_text = months.get(month_abbr.lower(), month_abbr)
168205
day_text = day_to_text(day)
169206
return f'{year_text} {month_text} {day_text}'
170-
text = re.sub(pattern2, repl2, text)
207+
text = pattern2.sub(repl2, text)
171208

172-
# HónapRöv.Nap formátum (okt.23.)
173-
pattern3 = r'(' + month_abbrs + r')(\d{1,2})\.'
174-
def repl3(match):
175-
month_abbr = match.group(1)
176-
day = int(match.group(2))
209+
# 3. HónapRöv.Nap formátum (okt.23.)
210+
pattern3 = re.compile(r'(' + month_abbrs + r')(\d{1,2})\.')
211+
def repl3(m):
212+
month_abbr = m.group(1)
213+
day = int(m.group(2))
177214
month_text = months.get(month_abbr.lower(), month_abbr)
178215
day_text = day_to_text(day)
179216
return f'{month_text} {day_text}'
180-
text = re.sub(pattern3, repl3, text)
217+
text = pattern3.sub(repl3, text)
181218

182-
# HónapRöv. Nap-án formátum (okt. 23-án)
183-
pattern4 = r'(' + month_abbrs + r')\s+(\d{1,2})-án'
184-
def repl4(match):
185-
month_abbr = match.group(1)
186-
day = int(match.group(2))
219+
# 4. HónapRöv. Nap-án formátum (okt. 23-án)
220+
pattern4 = re.compile(r'(' + month_abbrs + r')\s+(\d{1,2})-án')
221+
def repl4(m):
222+
month_abbr = m.group(1)
223+
day = int(m.group(2))
187224
month_text = months.get(month_abbr.lower(), month_abbr)
188225
day_text = day_to_text(day) + 'n'
189226
return f'{month_text} {day_text}'
190-
text = re.sub(pattern4, repl4, text)
227+
text = pattern4.sub(repl4, text)
228+
229+
# 5. Maradék rövid hónapnevek: dec. -> december stb.
230+
# (ezeket nem köti nap vagy év, csak önállóan szerepelnek)
231+
pattern5 = re.compile(r'(?<!\w)(' + month_abbrs + r')(?!\w)')
232+
def repl5(m):
233+
abb = m.group(1).lower()
234+
return months.get(abb, abb)
235+
text = pattern5.sub(repl5, text)
191236

192237
return text
193238

@@ -238,11 +283,12 @@ def normalize(text):
238283
force_changes = load_force_changes('force_changes.csv')
239284
changes = load_changes('changes.csv')
240285

286+
text = replace_roman_numerals(text)
241287
text = apply_force_changes(text, force_changes)
242288
text = apply_changes(text, changes)
243289
text = replace_dates(text)
244290
text = replace_times(text)
245-
text = replace_ordinals(text, ordinals)
291+
text = replace_ordinals(text)
246292
text = replace_numbers(text)
247293
text = remove_unwanted_characters(text)
248294
text = remove_duplicate_spaces(text)
@@ -252,6 +298,7 @@ def normalize(text):
252298

253299
if __name__ == "__main__":
254300
# Példa szöveg
255-
sample_text = "Ez egy példa, KENY, szöveg 10% és 7:15 időponttal 2015.10.23. dátummal. Chartmen"
301+
sample_text = ("Ez egy példa szöveg 2023.10.23-án, ami tartalmaz római számokat: VI, és arab számokat: 1234. "
302+
"Ezen kívül van benne időpont is: 12:30:45, és dátumok is: okt. 23-án.")
256303
normalized_text = normalize(sample_text)
257304
print(normalized_text)

0 commit comments

Comments
 (0)