Recursive AI

Change the speech model cache directory in C#

OneSpeech is a free, open-source speech recognition library for .NET from Recursive AI. MIT or Apache-2.0, no native dependencies.

Choose where OneSpeech stores downloaded models and the files it converts for inference.

Terminal
dotnet add package RecursiveAI.OneSpeech

Requires .NET 10 (net10.0); .NET 9 and earlier aren’t supported.

C#
using OneSpeech.Catalog;
var home = Environment.GetFolderPath(
    Environment.SpecialFolder.UserProfile);
ModelStore.Default = new ModelStore(
    cacheDirectory: Path.Join(home, "speech-models"));
Console.WriteLine("Cache configured.");

Unzip the example, then dotnet run.

Prints:

Text
Cache configured.

The full program

C#
using OneSpeech.Catalog;
using static System.Environment;
 
var cache = Path.Combine(
    GetFolderPath(SpecialFolder.UserProfile),
    "speech-models");
ModelStore.Default = new ModelStore(cacheDirectory: cache);
Console.WriteLine("Cache configured.");
Console.WriteLine($"Absolute path: {Path.IsPathFullyQualified(ModelStore.Default.CacheDirectory)}");
Console.WriteLine($"Selected directory: {ModelStore.Default.CacheDirectory == Path.GetFullPath(cache)}");

The full program configures the process-wide store and checks the selected path; it downloads nothing. Use a directory only your account can write. Later pulls report ordinary I/O errors for permission or storage failures.

Text
Cache configured.
Absolute path: True
Selected directory: True

Variations

Use the environment variable instead of a constructor override. Set it before creating the store:

C#
using OneSpeech.Catalog;
var cache = Path.Join(
    Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
    "speech-models");
Environment.SetEnvironmentVariable("ONESPEECH_MODEL_CACHE", cache);
var store = new ModelStore();
Console.WriteLine(store.CacheDirectory == Path.GetFullPath(cache));
Text
True

You can also set the directory before starting the application. On Linux or macOS:

Terminal
export ONESPEECH_MODEL_CACHE="$HOME/speech-models"

On Windows, set it for future terminals:

BAT
setx ONESPEECH_MODEL_CACHE "%USERPROFILE%\speech-models"

Open a new terminal after setx. These settings apply only when you omit the cacheDirectory constructor argument.

The short answer

Pass cacheDirectory to ModelStore, then assign that store to ModelStore.Default before starting high-level Speech requests. Alternatively, set ONESPEECH_MODEL_CACHE before constructing the store. The constructor argument wins over the environment variable; the platform default is used only when neither is supplied.

Configuring a store does not fetch any models. The example reports the selected path properties without printing your user-directory name. It does not move an existing cache or change requests that have already started.

How do I change the model cache directory?

Use an application-specific directory under your own user profile, as the snippet at the top does. CacheDirectory is the absolute cache root. A relative constructor argument is resolved to a full path, so a path derived explicitly from the user profile avoids depending on the application’s current working directory.

There are two separate choices: which store your code holds and which store the high-level API uses. Constructing a local store variable affects only calls you make through that instance. Assigning it to ModelStore.Default supplies the process-wide store used by Speech. Make that assignment during startup, before concurrent requests. Replacing the default does not alter requests already in progress or dispose borrowed model sources.

If configuration comes from the process environment, the variation above reads ONESPEECH_MODEL_CACHE through a newly constructed store. Changing that variable later does not rewrite the path held by an existing store. For deployed applications, set the environment before startup rather than changing it while work is running.

Where are downloaded speech models stored?

Without an override, Windows uses LocalApplicationData/OneSpeech/models. macOS uses ~/Library/Caches/OneSpeech/models. Other platforms use $XDG_CACHE_HOME/onespeech/models, falling back to ~/.cache/onespeech/models. These are OneSpeech’s own cache rules; environment variables for another model client do not replace them.

The cache contains verified publisher files and registered runtime conversions, not merely a single weights file. Model subdirectories depend on the model ID, pinned revision and upstream filenames and digests. Different revisions therefore cannot silently reuse an old pin. Do not construct subdirectory names yourself; obtain a resolved model from PullAsync when you need its directory.

Use a trusted per-user location, not a directory writable by unrelated users. Do not replace model files or cache directories with symbolic links. This is a trust requirement for local files, not a filesystem sandbox.

Does changing the cache directory download models again?

Assignment alone does not download anything. Later pulls acquire missing files in the selected location. A new empty location does not automatically inherit the files in an old cache. Conversely, files that are already present are rehashed on first open per store instance and do not cause network requests.

Verification state is kept in memory rather than in a writable disk marker. A corrupt cached file is removed and reported with ModelIntegrityException; retry explicitly if you want to fetch it again. A persistent .lock file coordinates pulls across processes. Its continued presence does not mean a download is still active, and deleting it can split locking between processes. Leave lock-file management to the library. See the cache and trust documentation for the full behavior.

All onespeech recipes