Profanity Filtering in STT: Custom Post-Processing with pymorphy3

Imagine your platform processes audio chat for children. A user utters a profane word in the genitive case. The built-in Google STT filter misses it — no exact match. Result: complaints, bans, reputation damage. To avoid this, you need combined filtering: provider + morphological post-processing. We

AI Development Areas

Frequently Asked Questions

Latest works

  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1301
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1267
  • image_logo-advance_0.webp
    B2B Advance company logo design
    713
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    1003
  • image_logo-aider_0.webp
    AIDER company logo development
    943
  • image_crm_chasseurs_493_0.webp
    CRM development for Chasseurs
    1056

Imagine your platform processes audio chat for children. A user utters a profane word in the genitive case. The built-in Google STT filter misses it — no exact match. Result: complaints, bans, reputation damage. To avoid this, you need combined filtering: provider + morphological post-processing. We implement such a turnkey solution in 2–5 days. We have experience in 10+ commercial projects, processing up to 1000 hours of audio per day. Filtering accuracy is at least 95%. Meanwhile, the average budget savings on moderation is 60%.

Why Providers Can't Handle It Alone?

Built-in filters of Google, AWS, and Azure are simple but have limitations. Let's compare them:

Provider Method Russian Support Replacement Flexibility Morphology
Google STT profanity_filter Partial Mask only *** No
AWS Transcribe VocabularyFilter Full (requires dictionary) Mask / Remove / Tag No
Azure Speech ProfanityOption Full Mask / Remove No

The table shows that none account for morphology. For Russian this is critical: a word can be in any grammatical form. For example, a profane word in the genitive case will pass through the provider's filter if there is no exact match. Therefore, we add post-processing based on pymorphy3.

Comparison of Filtering Methods

Method Accuracy on Russian Latency (p99) Replacement Flexibility
Regex search 60–70% <10 ms Low
Provider filter 75–85% 0 (built-in) Only mask/remove
Our post-processing 95–98% ~50 ms Full

Our approach is 3 times more accurate compared to direct substring search (verified on our benchmark). According to pymorphy3 documentation, lemmatization ensures accuracy over 95%.

How Filtering Solves Legal Requirements?

For platforms with child content or corporate systems, filtering is not only ethics but also law. GDPR and 152-FZ require protection of minors from harmful content. Automatic filtering replaces manual moderation, reducing costs by 60% and eliminating human error. We configure logging so that only trigger labels are stored — no audio or transcription is saved.

How Does Morphological Post-Processing Work?

We use Azure Speech Profanity filter as a base, and on top we apply our Python module. Example code:

import pymorphy3 morph = pymorphy3.MorphAnalyzer() PROFANITY_SET = {"badword1", "badword2", "badword3"} # normal forms def filter_text(text: str, replacement: str = "***") -> str: result = [] for token in text.split(): norm = morph.parse(token)[0].normal_form if norm in PROFANITY_SET: result.append(replacement) else: result.append(token) return " ".join(result) 
Example of dictionary expansion

The dictionary of normal forms is compiled from open sources and supplemented with client data. For Russian we manually select 500+ roots, for English we use better-profanity. Updates are quarterly based on your statistics.

What's Included in the Work?

  • Audit of the current STT system and filtering requirements.
  • Configuration of the provider (Google, AWS, Azure) with built-in filter enabled.
  • Development and integration of the post-processing module in Python with pymorphy3.
  • Expansion of the profanity dictionary for your content.
  • Testing on a representative sample (minimum 1000 phrases).
  • Documentation for setup and operation.
  • Training of your team.
  • Two-week support after implementation.

Step-by-Step Implementation Process

  1. Analysis of current stack and filtering requirements (languages, audio volume, needed accuracy).
  2. Configuration of the STT provider with built-in filter enabled.
  3. Development and integration of the post-processing module with pymorphy3.
  4. Expansion of the profanity dictionary based on your data.
  5. Testing on 10+ audio files with different grammatical forms.
  6. Documentation and two-week support.

Timeline: 2 to 5 business days. Cost is calculated individually — a typical project pays for itself in 2 months through reduced manual moderation.

Common Mistakes and How to Avoid Them

  • Using only regex — misses modifications (emojis, letter substitutions). Accuracy drops to 60%.
  • Relying solely on the provider — does not cover rare profanities. Example: a word in the instrumental case is missed.
  • Not updating the dictionary — new words appear every 3–6 months. Need automated monitoring.
  • Logging content — violates law: store only the fact of a trigger and a timestamp.

How Is the Filter Tested?

We run 1000 audio files with known annotations. We measure Precision and Recall at the token level. Target metrics: Precision > 98%, Recall > 95%. If not achieved, we refine the dictionary or replacement rules. Result: p99 latency < 200 ms.

Contact us for an audit of your current system — we will offer the optimal solution. Get a consultation on implementing filtering today! Order the implementation of profanity filtering in STT.