# GPT-SoVITS TTS Inference: Understanding cnhubert_path and bert_path Roles

> Discover GPT-SoVITS TTS inference roles for cnhubert_path and bert_path. Learn how these speech and text encoders enable high-quality TTS synthesis.

- Repository: [RVC-Boss/GPT-SoVITS](https://github.com/RVC-Boss/GPT-SoVITS)
- Tags: internals
- Published: 2026-03-07

---

**`cnhubert_path` loads the Chinese HuBERT speech encoder for acoustic embeddings, while `bert_path` loads the Chinese RoBERTa text encoder for linguistic embeddings—both essential for the two-stage TTS synthesis pipeline in GPT-SoVITS.**

In the GPT-SoVITS text-to-speech system, the `cnhubert_path` and `bert_path` configuration parameters determine which pretrained encoders handle acoustic and linguistic feature extraction. These paths point to the Chinese HuBERT speech encoder and Chinese RoBERTa text encoder respectively, forming the backbone of the inference pipeline that converts text into natural-sounding speech according to the RVC-Boss/GPT-SoVITS source code.

## The Role of cnhubert_path: Acoustic Feature Encoding

The `cnhubert_path` parameter specifies the location of the **Chinese HuBERT** checkpoint, which serves as the speech encoder in the TTS pipeline.

In [`GPT_SoVITS/feature_extractor/cnhubert.py`](https://github.com/RVC-Boss/GPT-SoVITS/blob/main/GPT_SoVITS/feature_extractor/cnhubert.py) (lines 22-33), the `CNHubert` class loads both the `HubertModel` and `Wav2Vec2FeatureExtractor` from this path. During inference, the model extracts **speech embeddings** (`hubert_feature`) from the input waveform or generated latent representations. As implemented in [`GPT_SoVITS/TTS_infer_pack/TTS.py`](https://github.com/RVC-Boss/GPT-SoVITS/blob/main/GPT_SoVITS/TTS_infer_pack/TTS.py) (lines 827-830), these acoustic embeddings feed directly into the VITS decoder via `self.vits_model.extract_latent`, enabling the synthesis of audio that preserves the speaker's timbre and prosody.

The `TTS` class initializes this encoder in the `init_cnhuhbert_weights` method (lines 476-480 of [`TTS.py`](https://github.com/RVC-Boss/GPT-SoVITS/blob/main/TTS.py)), loading the model to the configured device and setting it to evaluation mode.

## The Role of bert_path: Linguistic Feature Encoding

Conversely, `bert_path` points to the **Chinese RoBERTa-WWM-Ext-Large** checkpoint, which functions as the text encoder within the architecture.

According to [`GPT_SoVITS/TTS_infer_pack/TTS.py`](https://github.com/RVC-Boss/GPT-SoVITS/blob/main/GPT_SoVITS/TTS_infer_pack/TTS.py) (lines 484-488), the `init_bert_weights` method uses this path to instantiate `AutoTokenizer` and `AutoModelForMaskedLM`. The tokenizer converts input text into token IDs, while the BERT model produces **contextual token embeddings** (`bert_features`). These features are concatenated with phone embeddings and passed to the T2S (text-to-speech) transformer, providing rich linguistic information that enhances pronunciation accuracy, tone-sandhi handling, and prosody control.

The feature extraction occurs in `segment_and_extract_feature_for_text` (lines 904-938), where the BERT features are built, padded, and batched for efficient processing by the transformer decoder.

## Configuration Flow: From Defaults to Runtime

Both paths are resolved through a hierarchical configuration system defined in [`config.py`](https://github.com/RVC-Boss/GPT-SoVITS/blob/main/config.py) (lines 32-34), where default paths are specified for different model versions.

When instantiating the `TTS` class, the constructor reads these paths from the configuration dictionary (lines 336-338 of [`TTS.py`](https://github.com/RVC-Boss/GPT-SoVITS/blob/main/TTS.py)). If the provided path is `None`, empty, or points to a non-existent directory, the system falls back to the defaults defined in `self.default_configs[version]` (lines 48-53).

```python

# Path resolution with fallback logic from TTS.py lines 48-53 and 336-338

self.bert_base_path = self.configs.get("bert_base_path", None)
self.cnhuhbert_base_path = self.configs.get("cnhuhbert_base_path", None)

if (self.bert_base_path in [None, ""]) or (not os.path.exists(self.bert_base_path)):
    self.bert_base_path = self.default_configs[version]["bert_base_path"]
if (self.cnhuhbert_base_path in [None, ""]) or (not os.path.exists(self.cnhuhbert_base_path)):
    self.cnhuhbert_base_path = self.default_configs[version]["cnhuhbert_base_path"]

```

## Runtime Feature Extraction Workflow

During actual synthesis, both encoders operate in tandem to transform text into speech representations.

The BERT model processes tokenized input to generate contextual embeddings:

```python

# BERT feature extraction as implemented in the inference pipeline

bert_features = self.bert_model(**inputs).last_hidden_state  # (batch, seq_len, hidden)

```

Simultaneously, the CNHubert model extracts acoustic features from reference audio or intermediate waveforms:

```python

# CNHubert acoustic feature extraction (TTS.py line 827-830)

hubert_feature = self.cnhuhbert_model.model(wav16k.unsqueeze(0))["last_hidden_state"]

```

These complementary embeddings—linguistic from BERT and acoustic from HuBERT—converge in the VITS and T2S modules to produce the final audio output.

## Practical Implementation: Loading Custom Encoders

You can override the default encoder paths when initializing the `TTS` class to use custom pretrained models:

```python
from GPT_SoVITS.TTS_infer_pack.TTS import TTS

# Instantiate with custom encoder paths

tts = TTS(
    bert_base_path="path/to/custom-roberta",
    cnhuhbert_base_path="path/to/custom-hubert",
    version="v2"
)

# Run inference

audio = tts.infer_text("你好，欢迎使用 GPT-SoVITS！")

```

This configuration flexibility allows researchers to swap in domain-specific encoders without modifying the core library code, provided the model architectures remain compatible with the expected `AutoModelForMaskedLM` and `HubertModel` interfaces.

## Summary

- **`cnhubert_path`** specifies the Chinese HuBERT checkpoint location for extracting acoustic embeddings that guide the VITS decoder's timbre generation.
- **`bert_path`** defines the Chinese RoBERTa checkpoint location for producing contextual linguistic embeddings that feed the T2S transformer.
- Both paths support automatic fallback to defaults defined in [`config.py`](https://github.com/RVC-Boss/GPT-SoVITS/blob/main/config.py) if invalid paths are provided.
- The `TTS` class initializes these encoders via `init_cnhuhbert_weights` and `init_bert_weights` methods before inference.
- Runtime feature extraction occurs in `segment_and_extract_feature_for_text` (BERT) and the VITS latent extraction stage (CNHubert).

## Frequently Asked Questions

### What happens if cnhubert_path or bert_path points to a non-existent directory?

The `TTS` constructor validates both paths during initialization (lines 48-53 of [`TTS.py`](https://github.com/RVC-Boss/GPT-SoVITS/blob/main/TTS.py)). If either path is `None`, empty, or invalid, the system automatically falls back to the default paths specified in [`config.py`](https://github.com/RVC-Boss/GPT-SoVITS/blob/main/config.py) for the selected model version, ensuring the pipeline remains functional.

### Can I use standard English HuBERT or BERT models instead of the Chinese versions?

While the code architecture supports any compatible `HubertModel` or `AutoModelForMaskedLM` checkpoint, the GPT-SoVITS pipeline is optimized for Chinese phonetics and prosody. Substituting English models would likely degrade performance on Chinese text due to mismatched phoneme representations and tonal modeling, though the technical implementation in [`feature_extractor/cnhubert.py`](https://github.com/RVC-Boss/GPT-SoVITS/blob/main/feature_extractor/cnhubert.py) and [`TTS.py`](https://github.com/RVC-Boss/GPT-SoVITS/blob/main/TTS.py) would still load successfully.

### How do these paths affect VRAM usage during inference?

Both encoders reside in GPU memory when `self.configs.device` is set to CUDA. The Chinese HuBERT model typically consumes approximately 400-600MB VRAM, while the RoBERTa large model requires roughly 1.2-1.5GB. Specifying smaller custom checkpoints via these paths can reduce memory pressure, though quality trade-offs may occur.

### Where are the default paths for these encoders defined?

Default paths are hardcoded in [`config.py`](https://github.com/RVC-Boss/GPT-SoVITS/blob/main/config.py) (lines 32-34) and mapped by version keys in the `TTS` class's `default_configs` dictionary. The system expects these checkpoints to exist under `GPT_SoVITS/pretrained_models/` by default, though you can relocate them by updating the configuration file or passing absolute paths to the constructor.