Last updated: 2026-07-07
Overview
diffuseR is a functional R implementation of diffusion models, inspired by Hugging Face’s Python diffusers library. The package provides a simple, idiomatic R interface to state-of-the-art generative AI models for image generation and manipulation using base R and the torch package. No Python dependencies. Currently supports Windows and Linux cpu and cuda devices.
Example output
Installation
First install torch. As per this comment, using the pre-built binaries from https://torch.mlverse.org/docs/articles/installation#pre-built is heavily recommend. “The pre-built binaries bundle the necessary CUDA and cudnn versions, so you don’t need a global compatible system version of CUDA”:
options(timeout = 600) # increasing timeout is recommended since we will be downloading a 2GB file.
# For Windows and Linux: "cpu", "cu128" are the only currently supported
# For MacOS the supported are: "cpu-intel" or "cpu-m1"
kind <- "cu124"
version <- available.packages()["torch","Version"]
options(repos = c(
torch = sprintf("https://torch-cdn.mlverse.org/packages/%s/%s/", kind, version),
CRAN = "https://cloud.r-project.org" # or any other from which you want to install the other R dependencies.
))
install.packages("torch")
You can install the development version of diffuseR from GitHub:
# install.packages("devtools")
devtools::install_github("cornball-ai/diffuseR")
# Or
# install.packages("targets")
targets::install_github("cornball-ai/diffuseR")
Features
- Text-to-Image Generation: Stable Diffusion 2.1, SDXL, FLUX.1-schnell, and FLUX.2 Klein (fully native R torch implementations)
- Text-to-Video Generation: LTX-2.3 with synchronized audio
- Image-to-Image Generation: Modify existing images based on text prompts (SD 2.1 / SDXL)
- GPU-poor support: NF4 and fp8 quantization run the 12B FLUX.1 and 22B LTX-2.3 transformers on a 16GB card
- Scheduler Options: DDIM and FlowMatch Euler (static and dynamic shifting)
- Device Support: CPU and CUDA GPUs (including Blackwell RTX 50xx)
- R-native Interface: Functional programming approach that feels natural in R
Quick Start
Basic Usage
Warning: The first time you run the code below, it will download ~5.3GB of Stable Diffusion 2.1 CPU-only model files from Hugging Face and load them into memory. Ensure you have enough RAM, disk space, and a stable internet connection. Memory management with deep learning models is crucial, so consider using a machine with sufficient resources; ~8GB of free RAM is recommended for running Stable Diffusion 2.1 on CPU only.
options(timeout = 600) # increasing timeout is recommended since we will be downloading a 3.5GB file.
library(diffuseR)
torch::local_no_grad()
# Generate an image from text
cat_img <- txt2img(
prompt = "a photorealistic cat wearing sunglasses",
model = "sd21", # Specify the model to use, e.g., "sd21" for Stable Diffusion 2.1
download_models = TRUE, # Automatically download the model if not already present
steps = 30,
seed = 42,
filename = "cat.png",
)
# Clear out pipeline to free up GPU memory
pipeline <- NULL
torch::cuda_empty_cache()
Advanced Usage with GPU
The unet is the most computationally-intensive part of the model, so it is recommended to run it on a GPU if possible. The decoder and text encoder can be run on CPU if you have limited GPU memory. SDXL’s unet requires a minimum of 6GB of GPU memory (VRAM), while Stable Diffusion 2.1 requires a minimum of 2GB.
# Increasing timeout is recommended since we will be downloading 5.1 and 2.8GB model files, among others.
options(timeout = 1200)
library(diffuseR)
torch::local_no_grad() # Prevents torch from tracking gradients, which is not needed for inference
# Assign the various deep learning models to devices
model_name = "sdxl"
devices = list(unet = "cuda", decoder = "cpu",
text_encoder = "cpu", encoder = "cpu")
m2d <- models2devices(model_name = model_name, devices = devices,
unet_dtype_str = "float16", download_models = TRUE)
pipeline <- load_pipeline(model_name = model_name, m2d = m2d, i2i = TRUE,
unet_dtype_str = "float16")
# Generate an image from text
cat_img <- txt2img(
prompt = "a photorealistic cat wearing sunglasses",
model_name = model_name,
devices = devices,
pipeline = pipeline,
num_inference_steps = 30,
guidance_scale = 7.5,
seed = 42,
filename = "cat2.png",
)
gambling_cat <- img2img(
input_image = "cat2.png",
prompt = "a photorealistic cat throwing dice",
img_dim = 1024,
model_name = model_name,
devices = devices,
pipeline = pipeline,
num_inference_steps = 30,
strength = 0.75,
guidance_scale = 7.5,
seed = 42,
filename = "gambling_cat.png"
)
# Clear out pipeline to free up GPU memory
pipeline <- NULL
torch::cuda_empty_cache()
FLUX
FLUX.1-schnell (12B) and FLUX.2 Klein (4B) are step-distilled models: 4 denoising steps, no guidance. Both are quantized locally once at download time and fit comfortably on a 16GB GPU (measured on an RTX 5060 Ti: FLUX.1 1024x1024 in ~2 min at 8.7GB peak; FLUX.2 Klein in ~48s at 8.2GB peak).
library(diffuseR)
# FLUX.1-schnell: the HuggingFace repo is gated (Apache-2.0 weights,
# license click-through). Accept the license and set HF_TOKEN first.
# ~34GB download, one-time NF4 quantize to a 6.8GB artifact.
download_flux1()
txt2img_flux("An astronaut riding a horse on Mars, photorealistic",
seed = 7)
# FLUX.2 Klein 4B: ungated. ~16GB download, one-time fp8 quantize to
# a 3.9GB artifact.
download_flux2_klein()
txt2img_flux2("a red fox sitting in a snowy forest, digital art",
seed = 42)
# Or through the common dispatcher
txt2img("a lighthouse at dusk", model_name = "flux2")
Supported Models
Currently supported models:
- Stable Diffusion 2.1
- Stable Diffusion XL (SDXL)
- FLUX.1-schnell (12B, 4-step distilled)
- FLUX.2 Klein 4B (4-step distilled)
- LTX-2.3 Video (with audio)
Downloading Models
Models are automatically downloaded from HuggingFace on first use. For gated models (like FLUX.1-schnell), you need to:
- Create a HuggingFace account at https://huggingface.co
- Accept the model’s license agreement (visit the model page and click “Agree”)
- Create an access token at https://huggingface.co/settings/tokens
- Add to your
~/.Renviron:HF_TOKEN=hf_your_token_here
Manual download with hfhub:
# Install hfhub with HF_TOKEN fix (until PR merged upstream)
remotes::install_github("cornball-ai/hfhub@fix-gated-repos")
# Download a model
library(hfhub)
path <- hub_download("google/gemma-3-12b-it", "config.json")
# Or download entire model:
# path <- hub_snapshot("stabilityai/stable-diffusion-2-1")
Roadmap
Future plans for diffuseR include:
- Inpainting support
- Additional schedulers (PNDM, DPMSolverMultistep, Euler ancestral)
- FLUX.2 reference-image conditioning and img2img
- text-to-video generation (LTX-2.3)
How It Works
diffuseR supports two execution modes:
Native R torch (recommended for SDXL): Pure R implementations of VAE decoder, text encoders, and UNet. Required for Blackwell GPUs (RTX 50xx series) and recommended for best compatibility. Enable with use_native_* flags or use txt2img_sdxl() which defaults to native.
TorchScript (legacy): Pre-exported models from PyTorch. Still available for SD21 and older GPUs. Scripts to build TorchScript files are at diffuseR-TS.
No Python dependencies required for either mode.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
This project is licensed under the Apache 2. License - see the LICENSE file for details.
Acknowledgments
- Hugging Face for the original diffusers library
- Stability AI for Stable Diffusion
- The R and torch communities for their excellent tooling
Functions
auto_devices
diffuseR::auto_devicesbpe_tokenizer
diffuseR::bpe_tokenizerclear_vram
diffuseR::clear_vramclip_pooled_output
diffuseR::clip_pooled_outputCLIPTokenizer
diffuseR::CLIPTokenizerddim_scheduler_create
diffuseR::ddim_scheduler_createddim_scheduler_step
diffuseR::ddim_scheduler_stepdecode_bpe
diffuseR::decode_bpedownload_component
diffuseR::download_componentdownload_flux1
diffuseR::download_flux1download_flux2_klein
diffuseR::download_flux2_kleindownload_ltx2
diffuseR::download_ltx2download_model
diffuseR::download_modelencode_bpe
diffuseR::encode_bpeencode_qwen
diffuseR::encode_qwenencode_unigram
diffuseR::encode_unigramencode_with_gemma3
diffuseR::encode_with_gemma3encode_with_qwen3
diffuseR::encode_with_qwen3encode_with_t5
diffuseR::encode_with_t5filename_from_prompt
diffuseR::filename_from_promptflowmatch_calculate_shift
diffuseR::flowmatch_calculate_shiftflowmatch_scale_noise
diffuseR::flowmatch_scale_noiseflowmatch_scheduler_create
diffuseR::flowmatch_scheduler_createflowmatch_scheduler_step
diffuseR::flowmatch_scheduler_stepflowmatch_set_timesteps
diffuseR::flowmatch_set_timestepsflux_ada_layer_norm_continuous
diffuseR::flux_ada_layer_norm_continuousflux_ada_layer_norm_zero
diffuseR::flux_ada_layer_norm_zeroflux_ada_layer_norm_zero_single
diffuseR::flux_ada_layer_norm_zero_singleflux_apply_rotary_emb
diffuseR::flux_apply_rotary_embflux_attention
diffuseR::flux_attentionflux_double_block
diffuseR::flux_double_blockflux_is_quant_key
diffuseR::flux_is_quant_keyflux_load_pipeline
diffuseR::flux_load_pipelineflux_load_transformer
diffuseR::flux_load_transformerflux_memory_profile
diffuseR::flux_memory_profileflux_open_checkpoint
diffuseR::flux_open_checkpointflux_open_quantized
diffuseR::flux_open_quantizedflux_pack_latents
diffuseR::flux_pack_latentsflux_pos_embed
diffuseR::flux_pos_embedflux_prepare_latent_image_ids
diffuseR::flux_prepare_latent_image_idsflux_quantize
diffuseR::flux_quantizeflux_single_block
diffuseR::flux_single_blockflux_transformer
diffuseR::flux_transformerflux_unpack_latents
diffuseR::flux_unpack_latentsflux2_bn_normalize
diffuseR::flux2_bn_normalizeflux2_double_block
diffuseR::flux2_double_blockflux2_empirical_mu
diffuseR::flux2_empirical_muflux2_feed_forward
diffuseR::flux2_feed_forwardflux2_is_quant_key
diffuseR::flux2_is_quant_keyflux2_load_pipeline
diffuseR::flux2_load_pipelineflux2_modulation
diffuseR::flux2_modulationflux2_pack_latents
diffuseR::flux2_pack_latentsflux2_parallel_self_attention
diffuseR::flux2_parallel_self_attentionflux2_patchify_latents
diffuseR::flux2_patchify_latentsflux2_prepare_latent_ids
diffuseR::flux2_prepare_latent_idsflux2_prepare_text_ids
diffuseR::flux2_prepare_text_idsflux2_single_block
diffuseR::flux2_single_blockflux2_transformer
diffuseR::flux2_transformerflux2_unpack_latents_with_ids
diffuseR::flux2_unpack_latents_with_idsflux2_unpatchify_latents
diffuseR::flux2_unpatchify_latentsflux2_vae_decoder
diffuseR::flux2_vae_decodergemma3_config_ltx2
diffuseR::gemma3_config_ltx2gemma3_text_model
diffuseR::gemma3_text_modelgemma3_tokenizer
diffuseR::gemma3_tokenizerimg2img
diffuseR::img2imgis_blackwell_gpu
diffuseR::is_blackwell_gpulatents_to_video
diffuseR::latents_to_videoload_decoder_safetensors
diffuseR::load_decoder_safetensorsload_decoder_weights
diffuseR::load_decoder_weightsload_flux2_vae_decoder
diffuseR::load_flux2_vae_decoderload_gemma3_text_encoder
diffuseR::load_gemma3_text_encoderload_model_component
diffuseR::load_model_componentload_pipeline
diffuseR::load_pipelineload_qwen3_text_encoder
diffuseR::load_qwen3_text_encoderload_t5_text_encoder
diffuseR::load_t5_text_encoderload_text_encoder_safetensors
diffuseR::load_text_encoder_safetensorsload_text_encoder_weights
diffuseR::load_text_encoder_weightsload_text_encoder2_weights
diffuseR::load_text_encoder2_weightsload_to_gpu
diffuseR::load_to_gpuload_unet_sdxl_weights
diffuseR::load_unet_sdxl_weightsload_unet_weights
diffuseR::load_unet_weightsltx23_ada_layer_norm_single
diffuseR::ltx23_ada_layer_norm_singleltx23_adain_filter_latent
diffuseR::ltx23_adain_filter_latentltx23_antialias_act1d
diffuseR::ltx23_antialias_act1dltx23_apply_interleaved_rotary_emb
diffuseR::ltx23_apply_interleaved_rotary_embltx23_apply_split_rotary_emb
diffuseR::ltx23_apply_split_rotary_embltx23_attention
diffuseR::ltx23_attentionltx23_audio_causal_conv2d
diffuseR::ltx23_audio_causal_conv2dltx23_audio_decoder
diffuseR::ltx23_audio_decoderltx23_audio_downsample
diffuseR::ltx23_audio_downsampleltx23_audio_encoder
diffuseR::ltx23_audio_encoderltx23_audio_mel_frontend
diffuseR::ltx23_audio_mel_frontendltx23_audio_resnet_block
diffuseR::ltx23_audio_resnet_blockltx23_audio_upsample
diffuseR::ltx23_audio_upsampleltx23_audio_vae
diffuseR::ltx23_audio_vaeltx23_causal_conv3d
diffuseR::ltx23_causal_conv3dltx23_census
diffuseR::ltx23_censusltx23_connector_transformer_1d
diffuseR::ltx23_connector_transformer_1dltx23_denormalize_latents
diffuseR::ltx23_denormalize_latentsltx23_distilled_sigmas
diffuseR::ltx23_distilled_sigmasltx23_downsample1d
diffuseR::ltx23_downsample1dltx23_encode_audio
diffuseR::ltx23_encode_audioltx23_encode_video_frames
diffuseR::ltx23_encode_video_framesltx23_feed_forward
diffuseR::ltx23_feed_forwardltx23_fp8_linear
diffuseR::ltx23_fp8_linearltx23_get_timestep_embedding
diffuseR::ltx23_get_timestep_embeddingltx23_is_fp8_cast_key
diffuseR::ltx23_is_fp8_cast_keyltx23_kaiser_sinc_filter1d
diffuseR::ltx23_kaiser_sinc_filter1dltx23_latent_upsampler
diffuseR::ltx23_latent_upsamplerltx23_load_group
diffuseR::ltx23_load_groupltx23_load_pipeline
diffuseR::ltx23_load_pipelineltx23_load_transformer_fp8
diffuseR::ltx23_load_transformer_fp8ltx23_load_transformer_nf4
diffuseR::ltx23_load_transformer_nf4ltx23_load_upsampler
diffuseR::ltx23_load_upsamplerltx23_map_audio_vae_key
diffuseR::ltx23_map_audio_vae_keyltx23_map_connector_key
diffuseR::ltx23_map_connector_keyltx23_map_dit_key
diffuseR::ltx23_map_dit_keyltx23_map_vae_key
diffuseR::ltx23_map_vae_keyltx23_map_vocoder_key
diffuseR::ltx23_map_vocoder_keyltx23_mel_stft
diffuseR::ltx23_mel_stftltx23_memory_profile
diffuseR::ltx23_memory_profileltx23_nf4_dequantize
diffuseR::ltx23_nf4_dequantizeltx23_nf4_linear
diffuseR::ltx23_nf4_linearltx23_nf4_quantize
diffuseR::ltx23_nf4_quantizeltx23_normalize_latents
diffuseR::ltx23_normalize_latentsltx23_open_checkpoint
diffuseR::ltx23_open_checkpointltx23_open_fp8_checkpoint
diffuseR::ltx23_open_fp8_checkpointltx23_per_channel_rms_norm
diffuseR::ltx23_per_channel_rms_normltx23_per_token_rms_norm
diffuseR::ltx23_per_token_rms_normltx23_prepare_conditioned_latents
diffuseR::ltx23_prepare_conditioned_latentsltx23_preprocess_frames
diffuseR::ltx23_preprocess_framesltx23_quantize_fp8
diffuseR::ltx23_quantize_fp8ltx23_quantize_nf4
diffuseR::ltx23_quantize_nf4ltx23_read_audio
diffuseR::ltx23_read_audioltx23_read_tail_frames
diffuseR::ltx23_read_tail_framesltx23_release_dequant_buffers
diffuseR::ltx23_release_dequant_buffersltx23_rms_norm
diffuseR::ltx23_rms_normltx23_rotary_pos_embed
diffuseR::ltx23_rotary_pos_embedltx23_rotary_pos_embed_1d
diffuseR::ltx23_rotary_pos_embed_1dltx23_set_attn_chunk
diffuseR::ltx23_set_attn_chunkltx23_snake_beta
diffuseR::ltx23_snake_betaltx23_split_keys
diffuseR::ltx23_split_keysltx23_stage2_distilled_sigmas
diffuseR::ltx23_stage2_distilled_sigmasltx23_text_connectors
diffuseR::ltx23_text_connectorsltx23_tone_map_latents
diffuseR::ltx23_tone_map_latentsltx23_transformer
diffuseR::ltx23_transformerltx23_transformer_block
diffuseR::ltx23_transformer_blockltx23_tune_gc
diffuseR::ltx23_tune_gcltx23_upsample1d
diffuseR::ltx23_upsample1dltx23_video_decoder3d
diffuseR::ltx23_video_decoder3dltx23_video_down_block3d
diffuseR::ltx23_video_down_block3dltx23_video_downsampler3d
diffuseR::ltx23_video_downsampler3dltx23_video_encoder3d
diffuseR::ltx23_video_encoder3dltx23_video_mid_block3d
diffuseR::ltx23_video_mid_block3dltx23_video_resnet_block3d
diffuseR::ltx23_video_resnet_block3dltx23_video_up_block3d
diffuseR::ltx23_video_up_block3dltx23_video_upsampler3d
diffuseR::ltx23_video_upsampler3dltx23_video_vae
diffuseR::ltx23_video_vaeltx23_vocoder
diffuseR::ltx23_vocoderltx23_vocoder_resblock
diffuseR::ltx23_vocoder_resblockltx23_vocoder_with_bwe
diffuseR::ltx23_vocoder_with_bwemodels2devices
diffuseR::models2devicesoffload_to_cpu
diffuseR::offload_to_cpupost_quant_conv
diffuseR::post_quant_convpreprocess_image
diffuseR::preprocess_imagequant_conv
diffuseR::quant_convqwen_bpe_tokenizer
diffuseR::qwen_bpe_tokenizerqwen3_encoder
diffuseR::qwen3_encodersave_frames
diffuseR::save_framessave_image
diffuseR::save_imagesave_video
diffuseR::save_videosave_video_ltx23
diffuseR::save_video_ltx23scheduler_add_noise
diffuseR::scheduler_add_noisesdxl_memory_profile
diffuseR::sdxl_memory_profilet5_encoder
diffuseR::t5_encodertext_encoder_native
diffuseR::text_encoder_nativetext_encoder2_native
diffuseR::text_encoder2_nativetokenize_gemma3
diffuseR::tokenize_gemma3txt2img
diffuseR::txt2imgtxt2img_flux
diffuseR::txt2img_fluxtxt2img_flux2
diffuseR::txt2img_flux2txt2img_sd21
diffuseR::txt2img_sd21txt2img_sdxl
diffuseR::txt2img_sdxltxt2vid_ltx2
diffuseR::txt2vid_ltx2unet_native
diffuseR::unet_nativeunet_native_from_torchscript
diffuseR::unet_native_from_torchscriptunet_sdxl_native
diffuseR::unet_sdxl_nativeunet_sdxl_native_from_torchscript
diffuseR::unet_sdxl_native_from_torchscriptunigram_tokenizer
diffuseR::unigram_tokenizervae_decoder_native
diffuseR::vae_decoder_nativevocab_size
diffuseR::vocab_sizevram_report
diffuseR::vram_reportwrite_wav
diffuseR::write_wav