Skip to contents

The fathom package allows R users to qualitatively code and measure a corpus of text, images, audio, or video with local large language models (LLMs), where every answer comes back as a probability rather than a word. This page helps you install the package, confirm that your Ollama server is up and running, and configure the additional software tools required to evaluate an audio or video corpus.

Installation

fathom is distributed through R-Universe.

install.packages(
  "fathom",
  repos = c("https://alcocer-jj.r-universe.dev", "https://cloud.r-project.org")
)

You also need a running Ollama server at version 0.12.11 or later and at least one instruction-following model pulled. Ollama provides a quick start tutorial on how to get set up. Ollama runs on macOS, Windows, and Linux.

Tested Ollama models

The following Ollama models were tested for compatibility.

Table of models tested

Because Ollama does not broadly support native audio and video input yet, audio and video corpora rely on text and image capabilities through the prepare_audio() and prepare_video() functions.

Model Parameter Text Image
deepseek-llm 7B Yes No
deepseek-v2 16B Yes No
gemma3 4B, 12B, 27B Yes Yes
gemma4 12B, 26B, 31B Yes Yes
granite4.1 3B, 8B, 30B Yes No
llama3.2 3B Yes No
mistral 7B Yes No
mistral-small 24B Yes No
mistral-small3.1 24B Yes Yes
mistral-small3.2 24B Yes Yes
nemotron-cascade-2 30B Yes No
olmo-3.1 32B1 Yes No
qwen3.5 9B, 27B Yes Yes
qwen3.6 35B Yes Yes
qwen3.8 27B Yes Yes

Checking the server and the model

With Ollama installed and models pulled, ollama_backend() confirms the server is answering and the model is there. If called without a model name, the function lists the models you have installed and their capabilities.

ollama_backend()
#> Models on http://localhost:11434
#>
#>   deepseek-llm:7b           4.0 GB   7B Q4_0        text
#>   deepseek-r1:32b          19.9 GB   32.8B Q4_K_M   text
#>   deepseek-v2:16b           8.9 GB   15.7B Q4_0     text
#>   gemma3:27b               17.4 GB   27.4B Q4_K_M   text, image
#>   gemma4:31b               19.9 GB   31.3B Q4_K_M   text, image
#>   granite4.1:30b           17.5 GB   28.9B Q4_K_M   text
#>   ministral-3:14b           9.1 GB   13.9B Q4_K_M   text, image
#>   mistral-small:24b        14.3 GB   23.6B Q4_K_M   text
#>   mistral-small3.2:24b     15.2 GB   24.0B Q4_K_M   text, image
#>   nemotron3:33b            27.6 GB   33.0B Q4_K_M   text, image
#>   olmo-3:32b               19.5 GB   32.2B Q4_K_M   text
#>   olmo-3.1:32b-instruct    19.5 GB   32.2B Q4_K_M   text
#>   qwen3.5:27b              17.4 GB   27.8B Q4_K_M   text, image
#>   qwen3.6:35b              23.9 GB   36.0B Q4_K_M   text, image
#>
#> Error: `model` is required. Paste one of the tags above, e.g.
#>         ollama_backend("deepseek-llm:7b")

Working with an audio or video corpus

The following tools are required if you want to work with an audio or video corpus, as Ollama does not broadly support native audio and video input yet.

ffmpeg

Both prepare_audio() and prepare_video() need it. Video is read through it directly, and the recognizers below load audio through it, so a recording in any format, a bare .wav included, needs it too.

ffmpeg can be installed via Homebrew, an open-source package manager that runs in the terminal.2

Run this in a terminal window.

brew install ffmpeg

Then confirm the installation worked.

ffmpeg -version

ffmpeg can be installed via WinGet, Windows’ native package manager for the command line.3

Run this in a PowerShell window.

winget install -e --id Gyan.FFmpeg

Restart the PowerShell window, then confirm the installation worked.

ffmpeg -version

ffmpeg can be installed via APT, the command-line package manager that Debian and Ubuntu ship with.4

Run this in a terminal window.

sudo apt install ffmpeg

Then confirm the installation worked.

ffmpeg -version

whisperx

prepare_audio() and prepare_video() transcribe with whisperx, which runs on macOS, Windows, or Linux. Alternatively, Apple Silicon users can use whispermlx, the same tool with its inference backend replaced by MLX and optimized for M-series chips. To use it, pass tool = "whispermlx", since whisperx is the default.

whisperx can be installed via uv, a package manager that installs Python command-line tools into isolated environments.5

Run this in a terminal window.

uv tool install whisperx # or swap with whispermlx

Then confirm the installation worked.

whisperx --version # or swap with whispermlx

Then, in R, confirm your environment can see it, along with ffmpeg.6

Sys.which("whisperx") # or swap with whispermlx
Sys.which("ffmpeg")

whisperx can be installed via uv, a package manager that installs Python command-line tools into isolated environments.7

Run this in a PowerShell window.

uv tool install whisperx

Then confirm the installation worked.

whisperx --version

Then, in R, confirm your environment can see it, along with ffmpeg.8

Sys.which("whisperx")
Sys.which("ffmpeg")

whisperx can be installed via uv, a package manager that installs Python command-line tools into isolated environments.9

Run this in a terminal window.

uv tool install whisperx

Then confirm the installation worked.

whisperx --version

Then, in R, confirm your environment can see it, along with ffmpeg.10

Sys.which("whisperx")
Sys.which("ffmpeg")

HuggingFace read token

Both the prepare_audio() and prepare_video() functions require a HuggingFace (HF) API token when setting diarize_names = TRUE, as the diarization model the package uses is gated. However, transcription, alignment, and voice activity detection all run from ungated weights, so only the labeling of speakers requires that extra step. To get access to the gated model, sign in to your HF account and accept the conditions on the model webpage. Then, create a read token at hf.co/settings/tokens and add it to your ~/.Renviron as a line like this one.

HF_TOKEN=hf_yourtokenhere

Restart your R session, confirm that the token is available, and save it to an object to be passed as hf_token later.

Sys.getenv("HF_TOKEN")

hf_token <- Sys.getenv("HF_TOKEN")

Workflow summary

A full run can consist of five to seven steps depending on whether your corpus of interest is not text and if you want an additional diagnostic check.

  1. Prepare a corpus with prepare_image(), prepare_audio() or prepare_video().
  2. Select a model with ollama_backend().
  3. Code the qualitative instrument with instrument(), and use preview() to see what the local LLM will read.
  4. Extract response probabilities with measure().
  5. Read the results with item_report() for descriptive summaries, use inspect_cases() to manually review some entries, and apply as_wide() to hand off for downstream analyses.
  6. Validate the LLM results with coding_sample() and validate_sample().
  7. Test the measurement with threshold_sensitivity() to assess if endorsement rates are sensitive to cut-point thresholds.

For an applied example, see A complete run.