Custom speech: Pronunciation dataset rejects cs-CZ diacritics in the spoken form, while plain-text datasets for the same locale accept them

VP 0 Reputation points
2026-09-09T09:00:05.9333333+00:00

I'm training a custom speech model for cs-CZ and need the recognizer to output German-origin

surnames in their German spelling while speakers pronounce them the Czech way — audio /ʃmiːt/

should transcribe as Schmid.

A Pronunciation dataset looks like the right tool, and the language-support table lists

cs-CZ as supporting pronunciation data. But every line whose spoken form contains a Czech

diacritic is rejected — while the same characters are accepted both by plain-text datasets in

the same locale, and by pronunciation datasets in another locale.

Environment

  • Region: Germany West Central
  • Uploaded via: Microsoft Foundry portal
  • Base model 20230111 for cs-CZ, base model 20210628 for hr-HR — the only base models offered for either locale

Repro: Pronunciation dataset, cs-CZ — fails

File is UTF-8 with BOM, one pronunciation per line, display form, single tab, spoken form

(verified by hex dump — the separator is a real U+0009 and the BOM is present):


Schmid	šmíd

Schmid	smid

Schmid	šum

Schmid	slon

Schmid	š m í d

Validation report:


{

    "acceptedLineCount": 2,

    "rejectedLineCount": 3,

    "details": [

        {

            "inputText": "Schmid\t\u0161m\u00edd",

            "errorKind": "SpokenFormIsInvalidError",

            "status": "Failed"

        },

        {

            "inputText": "Schmid\t\u0161um",

            "errorKind": "SpokenFormIsInvalidError",

            "status": "Failed"

        },

        {

            "inputText": "Schmid\t\u0161 m \u00ed d",

            "errorKind": "SpokenFormIsInvalidError",

            "status": "Failed"

        }

    ]

}

smid and slon (ASCII) were accepted; everything containing š or í was rejected.

Two details rule out the obvious explanations:

  • Not an unknown-word problem. šum is an ordinary Czech word and was still rejected, while the nonsense string smid was accepted. Splitting into space-delimited letters (š m í d) didn't help either.
  • Not my encoding. The service echoes the input back correctly decoded in inputText (\u0161m\u00edd), so the file was read as intended UTF-8 and the line was parsed before being rejected on content.

Control 1: plain-text dataset, same cs-CZ project — accepted

A plain-text (Language) dataset uploaded to the same project, same region, same base model

accepts all three of these lines, no rejections:


Pan Schmid dnes nepřijde.

Pan Šmíd dnes nepřijde.

Příliš žluťoučký kůň úpěl ďábelské ódy.

The first two lines are the same sentence with the German and the Czech spelling of the name,

and both are accepted — including Šmíd with the very characters that the pronunciation

dataset rejects. The third line covers most of the Czech diacritic inventory (ř ž ť ů ě ď ó)

and is likewise accepted.

So the accepted character set isn't a property of the locale, the resource, the region or the

base model. š and í are fine for cs-CZ in one dataset kind and rejected in another.

Control 2: Pronunciation dataset, hr-HR — accepted

An equivalent pronunciation dataset for Croatian customization was accepted in full, every

line, no rejections:


Apple	epl

Cash2Go	kaš tu go

Cash2Go	keš tu go

Phishing	fišing

PlayStation	plejstejšn

Twitch	tvič

š is U+0161 and č is U+010D in both languages — the identical codepoints. A validator

applying a genuine global restriction on non-ASCII input could not accept plejstejšn and

tvič here and reject šum for Czech. Note the Croatian model is the older base model

(20210628 vs 20230111), so base model vintage doesn't explain the Czech failure either.

Taken together, the two controls point at the accepted character set for the spoken form in

Pronunciation datasets specifically, being missing or misconfigured for cs-CZ.

Docs

Questions

  1. Is the cs-CZ pronunciation validator's character set intended to be ASCII-only, or is it misconfigured — given that plain text accepts these characters for the same locale and hr-HR accepts the same codepoints for the same dataset kind?
  2. Is it tied to the base model? Only 20230111 is offered for cs-CZ, so I have no newer version to try. If a fixed base model exists or is planned, please point me at it.
  3. If it's intended, is there any supported way to express Czech pronunciation in a Pronunciation dataset? There is no ASCII spelling that produces /ʃ/ under Czech grapheme-to-phoneme rules (sch reads as /sx/), so I don't see one.
  4. Does the same restriction apply to the display form? Everything tested here had an ASCII display form (Schmid, and likewise in the Croatian file), but real Czech output needs Šmíd, Schmidová.
  5. If pronunciation datasets can't work for cs-CZ, is audio + human-labeled transcript the recommended path for this scenario? Custom display text formatting isn't an option — cs-CZ isn't in its supported locale list.

Kind regards,

Azure Speech in Foundry Tools
0 comments No comments

1 answer

Sort by: Newest
  1. Suhail Ahamed J 0 Reputation points Microsoft External Staff
    2026-09-09T16:15:45.9133333+00:00

    Hello @VP ,
    Greetings,

    Thank you for providing such a well-constructed reproduction. The two controls plain-text cs-CZ accepting š/í, and hr-HR pronunciation accepting the identical codepoints on an older base model help isolate the issue to the spoken-form validator specifically for cs-CZ. I won’t ask you to repeat tests you’ve already ruled out.

    In short, I would not recommend trying to address this through the pronunciation dataset. For cs-CZ, it currently cannot express /ʃ/, and even in cases where it does work, a pronunciation dataset is the least flexible of the available customization mechanisms.

    Your use case where the audio is Czech in pronunciation, but the expected output follows German orthographic conventions is fundamentally a lexical/acoustic mapping problem. This is precisely the type of behavior that audio paired with human-labeled transcripts is designed to capture.

    There are two viable paths forward: one that can be deployed this week without any model training, and another that addresses the behavior directly within the model.

    Answers to your questions:

    1)ASCII-only by design, or misconfigured?
    Not documented as a restriction anywhere. Given plain-text cs-CZ accepts these characters and hr-HR accepts the same codepoints in the same dataset kind, the behavior is inconsistent with both the docs and the rest of the service. I'd treat it as a defect, not a contract so don't design around it as if it were stable.

    2)Tied to the base model?
    Almost certainly not. hr-HR passes on 20210628, which is older than your cs-CZ 20230111. Base-model vintage doesn't correlate. I'm not aware of a newer cs-CZ base model, and I won't name one I can't confirm check Foundry → Custom speech → Train model → Base model for the current list in Germany West Central.

    3)Any supported way to express Czech pronunciation in a pronunciation dataset?
    Not for /ʃ/ with an ASCII spoken form your sch → /sx/ analysis is correct, and there's no other Czech grapheme sequence that yields /ʃ/. So: no, and this route is a dead end for your use case regardless of the validator.

    **
    4)Does the restriction apply to the display form?**
    Untested in your reproduction every line you submitted had an ASCII display form. There's a one-line test that settles it; see step 0 below.

    5)Is audio + human-labeled transcript the recommended path?
    Yes and it would be my recommendation even if the pronunciation dataset worked. It's the only dataset type that trains the acoustic side, which is what you actually need here. Confirmed on your other point: custom display text formatting doesn't list cs-CZ, so that's correctly ruled out.

    Step 0 - Settle the display-form question

    Upload a pronunciation dataset with exactly these two lines and read the validation report:

    Šmíd	smid
    Schmidova	smidova
    
    • If line 1 passes → the restriction is scoped to the spoken form only, and display-side diacritics are fine. Useful to know for any future locale work.
    • If line 1 fails with a different errorKind (e.g. a display-form error) → the whole dataset kind is ASCII-gated for cs-CZ.

    I have provided two option you can follow any according to your convinence
    Option A - Ship now, no retraining (deterministic)
    This gets you correct output today and is worth keeping permanently as a safety net, even after you train a model.

    1. Let the recognizer output native Czech spelling. The stock cs-CZ model already transcribes /ʃmiːt/ as Šmíd . that is the correct Czech transcription of what was said. You're not fighting the model; you're fighting its output convention.

    2. Bias recognition with a phrase list at request time. Add your surname inventory in Czech spelling so the boundary and casing are stable:

    var phraseList = PhraseListGrammar.FromRecognizer(recognizer);
    phraseList.AddPhrase("Šmíd");
    phraseList.AddPhrase("Šmídová");
    phraseList.AddPhrase("Pan Šmíd");
    

    Phrase lists are a runtime hint - no training, no dataset, effective immediately. Confirm current phrase-list behaviour for cs-CZ against the Speech SDK docs , as support varies by feature and locale.

    3. Apply a normalization map in your application layer.

    Šmíd      → Schmid
    Šmída     → Schmida
    Šmídová   → Schmidová
    Šmídovi   → Schmidovi
    

    Two things make this more robust than it looks:

    • Czech is heavily inflected, so enumerate the case forms you'll actually see (nominative, genitive, dative, accusative, vocative, locative, instrumental), not just the lemma.
    • Apply the map on DisplayText only and keep the raw recognizer output in your logs so you can audit misfires.

    Trade-off, stated plainly: this is post-processing, not recognition. It won't help if the recognizer produces a different wrong token (e.g. smit, šmít). That's what Option B fixes.

    Option B - Train the mapping into the model (durable)
    This is the supported path and directly answers your Question 5.

    1. Collect audio

    • Record real speakers saying the surnames in running sentences, not isolated words. Isolated-word audio trains poorly and won't match your production acoustics.
    • Cover the inflected forms and realistic carrier phrases:
      • "Pan Schmid dnes nepřijde."
      • "Volal jsem panu Schmidovi včera."
      • "Paní Schmidová to potvrdila."
    • Match production conditions: same microphone class, sample rate, ambient noise profile, and speaker mix (gender, age, regional accent). A model trained on clean studio audio degrades sharply on a noisy call-centre line.
    • Aim for multiple distinct speakers per name a handful of speakers will overfit to their voices

    2. Write the transcripts as the target output

    This is the step that does the actual work:

    audio_001.wav	Pan Schmid dnes nepřijde.
    audio_002.wav	Volal jsem panu Schmidovi včera.
    audio_003.wav	Paní Schmidová to potvrdila.
    

    The speaker says /ʃmiːt/; the transcript says Schmid. That pairing is the mapping you were trying to encode in the pronunciation dataset and here it's fully supported, with no character-set gate in the way.

    Follow the transcript formatting rules (encoding, file naming, per-line pairing, audio format constraints) in Training and testing datasets. Note there are documented minimum and maximum audio durations for training verify the current figures for your locale before you start recording, so you don't under-collect and have to go back to the speakers.

    Do not include both Šmíd and Schmid in the training text if you want deterministic German-spelled output. Doing so trains two competing candidates for the same acoustics, and the model will emit whichever the LM happens to favour in context which is precisely the non-determinism you're trying to eliminate. **Include only the target spelling.

    4.Upload and train
    a) Foundry portal → your Custom speech project → Datasets → Upload data (guide)

    b) Train custom model → base model 20230111 → select both the audio + transcript dataset and the plain-text dataset (guide)

    c) Training with audio takes materially longer than text-only training. Plan for it.

    5. Evaluate against the baseline

    • Hold back 10–20% of your recordings as a test set never train on your evaluation data.
    • Run Test models against both the base model and your custom model and compare WER side by side.
    • WER alone will hide the thing you care about. Add a targeted check: of N utterances containing the surname, how many produced exactly Schmid? Track that number specifically.

    Two caveats I'd rather state than gloss over

    • I can't see your resource, quota, or training-job status anything account-specific needs to go through the Azure Portal or your support channel.
    • Dataset limits, supported audio formats, minimum training durations, and locale/feature support all change. Verify the specifics against current Microsoft Learn documentation before you commit to a recording effort.

    If you post the Step 0 result, I'll fold it back into this thread so the next person hitting the cs-CZ validator gets the complete picture. Happy to review your transcript formatting or test-set design if you want a second pair of eyes before you record.

    Help make this community better for everyone: if this answer resolved your issue, please accept it or upvote it. If not, share more details in a comment so we can continue the discussion and find the right solution.

    Was this answer helpful?


Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.