Shion1305/stc

Simple Transcribe CLI

C++

0

2 commits

updated Jul 6, 2026

See the code

README

cohere-transcribe

A local, API-free command-line transcription tool for Cohere Transcribe.

cohere-transcribe transcribes local audio files entirely on your machine. It does not call the Cohere API. On first run it downloads the required model artifacts from Hugging Face, caches them locally, and runs inference locally with ONNX Runtime. Japanese (ja) is the default language.

cohere-transcribe speech.wav --language ja --output transcript.txt
  • Targets: macOS Apple Silicon (primary), Linux x86_64 (secondary)
  • Language: C++17 (C++20 compatible), CMake build
  • Runtime deps: ONNX Runtime, and curl for downloads. No Python required.

Table of contents


Installation

Prerequisites

  • CMake ≥ 3.18
  • A C++17 compiler (Apple Clang, Clang, or GCC ≥ 9)
  • curl on PATH (used to download model artifacts)
  • For inference: ONNX Runtime (the build can fetch a prebuilt release automatically — see below)

Build

git clone <this-repo> cohere-transcribe
cd cohere-transcribe

# Configure + build WITH the ONNX Runtime inference backend.
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DCOHERE_ENABLE_ONNX=ON
cmake --build build -j

# The binary is at build/cohere-transcribe
./build/cohere-transcribe --version

By default (-DCOHERE_ENABLE_ONNX=ON) the build looks for ONNX Runtime in this order:

  1. -DONNXRUNTIME_ROOT_DIR=/path/to/onnxruntime (an extracted prebuilt package)
  2. A system-installed ONNX Runtime (find_library)
  3. A pinned prebuilt release downloaded via CMake FetchContent

If you only want to build/test the non-inference parts (CLI, audio, tokenizer, downloader), configure without ONNX Runtime — the inference backend becomes a clear-error stub:

cmake -S . -B build            # COHERE_ENABLE_ONNX defaults to OFF
cmake --build build -j

Install

cmake --install build --prefix /usr/local   # installs bin/cohere-transcribe

Usage

# Transcribe to stdout (Japanese by default)
cohere-transcribe speech.wav

# Specify language and write to a file
cohere-transcribe speech.wav --language ja --output transcript.txt

# Short flags
cohere-transcribe speech.wav -l ja

# JSON output
cohere-transcribe speech.wav -l ja --json

# Pre-download model artifacts and exit
cohere-transcribe --download-only

# Use a custom model cache directory
cohere-transcribe speech.wav --model-dir ~/.cache/cohere-transcribe-cli/models

# Fail (do not download) if model artifacts are missing
cohere-transcribe --no-download speech.wav

Options

OptionDescription
-l, --language <code>Language code (default: ja)
-o, --output <file>Write transcript to a file instead of stdout
--jsonEmit JSON instead of plain text
--model-dir <path>Model cache directory
--download-onlyDownload model artifacts and exit
--no-downloadDo not download; fail if artifacts are missing
--threads <n>Number of CPU inference threads (default: auto)
--verboseDetailed logs on stderr
--versionPrint version and exit
-h, --helpShow help and exit

Hugging Face token setup

The Cohere Transcribe model may be gated (you must accept its terms) or the ONNX conversion may live in a private repo. To authenticate downloads:

  1. Visit the model page on Hugging Face and accept the terms / request access.

  2. Create a token at https://huggingface.co/settings/tokens.

  3. Export it before running:

    export HF_TOKEN=hf_xxxxxxxxxxxxxxxxxxxx
    cohere-transcribe --download-only
    

If the download requires login or terms acceptance, the tool prints a clear message and exits with a dedicated exit code (6), rather than failing opaquely.

Pointing at a different artifact repo

The base model is CohereLabs/cohere-transcribe-03-2026, but the ONNX int8 artifacts (cohere-encoder.int8.onnx, etc.) come from an ONNX conversion. Point the downloader at whichever repo hosts them:

export COHERE_TRANSCRIBE_HF_REPO=your-org/cohere-transcribe-onnx-int8
export COHERE_TRANSCRIBE_HF_REVISION=main   # optional, defaults to main

Model cache behavior

  • Default cache root: ~/.cache/cohere-transcribe-cli/models
  • Artifacts live under: .../models/cohere-transcribe-onnx-int8/
  • Required files for the ONNX MVP:
    • cohere-encoder.int8.onnx
    • cohere-encoder.int8.onnx.data
    • cohere-decoder.int8.onnx
    • tokens.txt

On startup the tool checks whether all required files exist with non-zero size:

  • If any are missing and --no-download is not set, it downloads them from Hugging Face (HTTPS via curl).
  • If any are missing and --no-download is set, it fails with exit code 4.
  • Files that already exist are never re-downloaded.
  • Concurrent invocations are serialized per file with an advisory lock, so two runs won't corrupt a shared partial download.

By default a fresh download is started each run (any stale .part is discarded) so a partial left by a previous run of a different revision can't be silently appended to. To enable cross-invocation resume for large files, export COHERE_TRANSCRIBE_RESUME=1; within a single run, curl --retry already resumes transient network failures.

Override the cache location with --model-dir (tilde ~ is expanded).


Output formats

Plain text (default) — just the transcript:

文字起こし結果...

JSON (--json):

{
  "language": "ja",
  "text": "...",
  "model": "cohere-transcribe-03-2026",
  "backend": "onnx",
  "duration_sec": 0.0
}

Exit codes

CodeMeaning
0Success
1Generic error
2Usage / command-line error
3Audio read / decode error
4Required model files missing and download disabled
5Download / network / IO failure
6Hugging Face login or terms acceptance required
7Backend / inference failure
8Tokenizer (tokens.txt) missing or malformed

Architecture

Module boundaries (src/):

FileResponsibility
main.cppOrchestration and top-level error handling
cli.cppArgument parsing and usage/version text
hf_downloader.cppHugging Face artifact download (resume, auth)
audio_loader.cppWAV decoding (PCM / IEEE float)
audio_resampler.cppMono downmix + 16 kHz resampling
tokenizer.cpptokens.txt loading and greedy token decoding
asr_backend.hppBackend interface (AsrBackend) + factory
onnx_backend.cppONNX Runtime backend (features + encoder/decoder)
decoder.cppGreedy decoding + argmax utilities
transcript_writer.cppPlain-text / JSON output
paths.cppModel cache path resolution

The backend is abstracted behind AsrBackend:

class AsrBackend {
public:
    virtual ~AsrBackend() = default;
    virtual std::string transcribe(
        const std::vector<float>& mono_pcm_16khz,
        const std::string& language,
        int max_new_tokens) = 0;
};

This lets a GGUF / CrispASR (or other) backend be added later without changing the CLI, audio, tokenizer, or download layers.


Known limitations

  • No timestamps. Output is plain text only.
  • No speaker diarization.
  • Single language works best. Specify the correct --language.
  • No long-form chunking (yet). Very long audio is capped by the decoder's max_new_tokens; chunking is planned (see roadmap).
  • WAV input only for the MVP. Non-WAV formats (mp3/m4a/flac/ogg) need a future ffmpeg/libavformat backend.
  • 16 kHz mono internally. Stereo is averaged; other sample rates are linearly resampled (a higher-quality resampler is planned).
  • Community ONNX conversion. Until an official C++ runtime path exists, the first backend relies on a community ONNX conversion, and the feature frontend (log-mel) is a Whisper-style approximation. Tensor I/O names can be overridden via COHERE_ENC_INPUT, COHERE_ENC_OUTPUT, COHERE_DEC_IDS, COHERE_DEC_HIDDEN, COHERE_DEC_MASK, and COHERE_DEC_LOGITS. The decoder is run without a KV cache; an export that requires KV-cache inputs is rejected early with a clear message.

Roadmap / TODO

  • Long-form chunking — window long audio into overlapping segments and stitch transcripts.
  • VAD / noise gate — voice-activity detection to skip silence and reduce hallucination.
  • ffmpeg / libavformat input — decode mp3/m4a/flac/ogg (see the TODO boundary in audio_loader.hpp).
  • GGUF / CrispASR backend — a second AsrBackend implementation.
  • Homebrew packagingbrew install cohere-transcribe.
  • Higher-quality resampling (libsamplerate / soxr).
  • KV-cached decoder export for faster autoregressive decoding.

Development

# Configure with tests (on by default) and build
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j

# Run the test suite
cd build && ctest --output-on-failure

Unit tests cover CLI parsing, tokenizer loading/decoding, model cache path resolution, WAV loading, and greedy decoding. An integration test drives the built binary end-to-end for the paths that don't require the model (--version, --help, usage errors, and --no-download with a missing model).

Contributors

Shion1305

2 commits

Shion1305/stc

Simple Transcribe CLI

C++

0

2 commits

updated Jul 6, 2026

See the code

README

cohere-transcribe

A local, API-free command-line transcription tool for Cohere Transcribe.

cohere-transcribe transcribes local audio files entirely on your machine. It does not call the Cohere API. On first run it downloads the required model artifacts from Hugging Face, caches them locally, and runs inference locally with ONNX Runtime. Japanese (ja) is the default language.

cohere-transcribe speech.wav --language ja --output transcript.txt
  • Targets: macOS Apple Silicon (primary), Linux x86_64 (secondary)
  • Language: C++17 (C++20 compatible), CMake build
  • Runtime deps: ONNX Runtime, and curl for downloads. No Python required.

Table of contents


Installation

Prerequisites

  • CMake ≥ 3.18
  • A C++17 compiler (Apple Clang, Clang, or GCC ≥ 9)
  • curl on PATH (used to download model artifacts)
  • For inference: ONNX Runtime (the build can fetch a prebuilt release automatically — see below)

Build

git clone <this-repo> cohere-transcribe
cd cohere-transcribe

# Configure + build WITH the ONNX Runtime inference backend.
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DCOHERE_ENABLE_ONNX=ON
cmake --build build -j

# The binary is at build/cohere-transcribe
./build/cohere-transcribe --version

By default (-DCOHERE_ENABLE_ONNX=ON) the build looks for ONNX Runtime in this order:

  1. -DONNXRUNTIME_ROOT_DIR=/path/to/onnxruntime (an extracted prebuilt package)
  2. A system-installed ONNX Runtime (find_library)
  3. A pinned prebuilt release downloaded via CMake FetchContent

If you only want to build/test the non-inference parts (CLI, audio, tokenizer, downloader), configure without ONNX Runtime — the inference backend becomes a clear-error stub:

cmake -S . -B build            # COHERE_ENABLE_ONNX defaults to OFF
cmake --build build -j

Install

cmake --install build --prefix /usr/local   # installs bin/cohere-transcribe

Usage

# Transcribe to stdout (Japanese by default)
cohere-transcribe speech.wav

# Specify language and write to a file
cohere-transcribe speech.wav --language ja --output transcript.txt

# Short flags
cohere-transcribe speech.wav -l ja

# JSON output
cohere-transcribe speech.wav -l ja --json

# Pre-download model artifacts and exit
cohere-transcribe --download-only

# Use a custom model cache directory
cohere-transcribe speech.wav --model-dir ~/.cache/cohere-transcribe-cli/models

# Fail (do not download) if model artifacts are missing
cohere-transcribe --no-download speech.wav

Options

OptionDescription
-l, --language <code>Language code (default: ja)
-o, --output <file>Write transcript to a file instead of stdout
--jsonEmit JSON instead of plain text
--model-dir <path>Model cache directory
--download-onlyDownload model artifacts and exit
--no-downloadDo not download; fail if artifacts are missing
--threads <n>Number of CPU inference threads (default: auto)
--verboseDetailed logs on stderr
--versionPrint version and exit
-h, --helpShow help and exit

Hugging Face token setup

The Cohere Transcribe model may be gated (you must accept its terms) or the ONNX conversion may live in a private repo. To authenticate downloads:

  1. Visit the model page on Hugging Face and accept the terms / request access.

  2. Create a token at https://huggingface.co/settings/tokens.

  3. Export it before running:

    export HF_TOKEN=hf_xxxxxxxxxxxxxxxxxxxx
    cohere-transcribe --download-only
    

If the download requires login or terms acceptance, the tool prints a clear message and exits with a dedicated exit code (6), rather than failing opaquely.

Pointing at a different artifact repo

The base model is CohereLabs/cohere-transcribe-03-2026, but the ONNX int8 artifacts (cohere-encoder.int8.onnx, etc.) come from an ONNX conversion. Point the downloader at whichever repo hosts them:

export COHERE_TRANSCRIBE_HF_REPO=your-org/cohere-transcribe-onnx-int8
export COHERE_TRANSCRIBE_HF_REVISION=main   # optional, defaults to main

Model cache behavior

  • Default cache root: ~/.cache/cohere-transcribe-cli/models
  • Artifacts live under: .../models/cohere-transcribe-onnx-int8/
  • Required files for the ONNX MVP:
    • cohere-encoder.int8.onnx
    • cohere-encoder.int8.onnx.data
    • cohere-decoder.int8.onnx
    • tokens.txt

On startup the tool checks whether all required files exist with non-zero size:

  • If any are missing and --no-download is not set, it downloads them from Hugging Face (HTTPS via curl).
  • If any are missing and --no-download is set, it fails with exit code 4.
  • Files that already exist are never re-downloaded.
  • Concurrent invocations are serialized per file with an advisory lock, so two runs won't corrupt a shared partial download.

By default a fresh download is started each run (any stale .part is discarded) so a partial left by a previous run of a different revision can't be silently appended to. To enable cross-invocation resume for large files, export COHERE_TRANSCRIBE_RESUME=1; within a single run, curl --retry already resumes transient network failures.

Override the cache location with --model-dir (tilde ~ is expanded).


Output formats

Plain text (default) — just the transcript:

文字起こし結果...

JSON (--json):

{
  "language": "ja",
  "text": "...",
  "model": "cohere-transcribe-03-2026",
  "backend": "onnx",
  "duration_sec": 0.0
}

Exit codes

CodeMeaning
0Success
1Generic error
2Usage / command-line error
3Audio read / decode error
4Required model files missing and download disabled
5Download / network / IO failure
6Hugging Face login or terms acceptance required
7Backend / inference failure
8Tokenizer (tokens.txt) missing or malformed

Architecture

Module boundaries (src/):

FileResponsibility
main.cppOrchestration and top-level error handling
cli.cppArgument parsing and usage/version text
hf_downloader.cppHugging Face artifact download (resume, auth)
audio_loader.cppWAV decoding (PCM / IEEE float)
audio_resampler.cppMono downmix + 16 kHz resampling
tokenizer.cpptokens.txt loading and greedy token decoding
asr_backend.hppBackend interface (AsrBackend) + factory
onnx_backend.cppONNX Runtime backend (features + encoder/decoder)
decoder.cppGreedy decoding + argmax utilities
transcript_writer.cppPlain-text / JSON output
paths.cppModel cache path resolution

The backend is abstracted behind AsrBackend:

class AsrBackend {
public:
    virtual ~AsrBackend() = default;
    virtual std::string transcribe(
        const std::vector<float>& mono_pcm_16khz,
        const std::string& language,
        int max_new_tokens) = 0;
};

This lets a GGUF / CrispASR (or other) backend be added later without changing the CLI, audio, tokenizer, or download layers.


Known limitations

  • No timestamps. Output is plain text only.
  • No speaker diarization.
  • Single language works best. Specify the correct --language.
  • No long-form chunking (yet). Very long audio is capped by the decoder's max_new_tokens; chunking is planned (see roadmap).
  • WAV input only for the MVP. Non-WAV formats (mp3/m4a/flac/ogg) need a future ffmpeg/libavformat backend.
  • 16 kHz mono internally. Stereo is averaged; other sample rates are linearly resampled (a higher-quality resampler is planned).
  • Community ONNX conversion. Until an official C++ runtime path exists, the first backend relies on a community ONNX conversion, and the feature frontend (log-mel) is a Whisper-style approximation. Tensor I/O names can be overridden via COHERE_ENC_INPUT, COHERE_ENC_OUTPUT, COHERE_DEC_IDS, COHERE_DEC_HIDDEN, COHERE_DEC_MASK, and COHERE_DEC_LOGITS. The decoder is run without a KV cache; an export that requires KV-cache inputs is rejected early with a clear message.

Roadmap / TODO

  • Long-form chunking — window long audio into overlapping segments and stitch transcripts.
  • VAD / noise gate — voice-activity detection to skip silence and reduce hallucination.
  • ffmpeg / libavformat input — decode mp3/m4a/flac/ogg (see the TODO boundary in audio_loader.hpp).
  • GGUF / CrispASR backend — a second AsrBackend implementation.
  • Homebrew packagingbrew install cohere-transcribe.
  • Higher-quality resampling (libsamplerate / soxr).
  • KV-cached decoder export for faster autoregressive decoding.

Development

# Configure with tests (on by default) and build
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j

# Run the test suite
cd build && ctest --output-on-failure

Unit tests cover CLI parsing, tokenizer loading/decoding, model cache path resolution, WAV loading, and greedy decoding. An integration test drives the built binary end-to-end for the paths that don't require the model (--version, --help, usage errors, and --no-download with a missing model).

Contributors

Shion1305

2 commits

Languages

C++

90.0%

CMake

10.0%