OpenCLIP
repository·main·Indexed 11 days ago
https://github.com/mlfoundations/open_clipAn open-source implementation of OpenAI's Contrastive Language-Image Pre-training (CLIP). It provides training infrastructure and a wide range of pretrained multimodal models, including CLIP, SigLIP, CoCa, and CLAP, with support for diverse datasets like LAION-400M, LAION-2B, and DataComp-1B.
What's inside OpenCLIP
- OpenCLIP is an open-source implementation of OpenAI's CLIP (Contrastive Language-Image Pre-training). It provides access to a wide variety of pretrained models trained on diverse datasets like LAION-400M, LAION-2B, and DataComp-1B. Developers can use OpenCLIP for zero-shot image classification and other multimodal tasks using models ranging from small experiments to large-scale architectures like ViT-bigG-14.
Reduce image token length in CLIPA
mainCLIPA uses token length reduction to implement an inverse scaling law for CLIP training. You can reduce image token length using the following strategies:
resize: Uses the--force-image-sizeflag to specify a target image size. This is generally the most effective strategy as it retains full image information.random mask: Randomly masks out image patches. Use the--force-patch-dropoutflag to specify the desired mask ratio.grid mask(Experimental): Preserves one patch in each 2x2 grid window. Implementation is not provided as resizing is preferred.block mask(Experimental): Keeps a single block and removes other patches. Implementation is not provided as resizing is preferred.
# Example usage for resizing --force-image-size 224 # Example usage for random masking --force-patch-dropout 0.5Important notice regarding the main branch training stack
mainThe
mainbranch of OpenCLIP uses a post-refactor training stack. This stack is organized aroundTrainingTaskwrappers, uses dict-based batches, supports FSDP2, and includes NaFlex image/audio pipelines.Warning for users:
- If you require the older, release-stable training API, you must pin to the
v3branch or the latest 3.x release on PyPI. - While inference for pretrained image/text models remains compatible, training scripts and downstream integrations should be reviewed for breaking changes when upgrading to the
mainbranch.
- If you require the older, release-stable training API, you must pin to the
Use gradient accumulation to simulate larger batches
mainTo simulate larger batch sizes without increasing GPU memory usage linearly, use the
--accum-freq kflag.If your per-GPU batch size (
--batch-size) ism, the effective batch size becomesk * m * num_gpus.Important Considerations:
- Increasing
--accum-freqabove 1 will keep samples/s approximately constant, but time-per-batch will double. - It is recommended to use
--grad-checkpointing,--local-loss, or--gather-with-gradto reduce batch size before relying solely on accumulation. - Using accumulation requires additional GPU memory to store features and data from all
mbatches in memory, and results inmloss computations instead of one.
- Increasing
Use multiple data sources with weighting
mainYou can train on multiple datasets by separating paths with
::in the--train-dataflag.- Sampling: Use
--dataset-resampledto enable sampling with replacement. - Weighting: Use
--train-data-upsampling-factorsto control the relative frequency of each source. For example,--train-data-upsampling-factors=1::2upsamples the second source twice as much as the first.
# Example: Training on two different datasets --train-data "/data/cc12m/cc12m-train-{0000..2175}.tar::/data/LAION-400M/{00000..41455}.tar" \ --train-data-upsampling-factors=1::2- Sampling: Use
New and experimental model families in OpenCLIP
mainThe
mainbranch introduces several new model families and features:- NaFlex CLIP/CLAP/GenLIP/GenLAP: Supports variable-resolution/aspect image towers (timm
naflexvit) or variable-duration audio using token-budget batching (use--use-naflexandnaflex_*configs). - Modern text tower: Configured via
text_cfg.text_arch="modern". Includes RoPE, SwiGLU/ReLU², RMSNorm, and various pooling options. - Variable-length text: Set
text_cfg.variable_text=trueto pad captions to the per-batch maximum instead of a fixed context length. - MaMMUT: A multimodal model using a single text decoder in two passes (bi-directional for contrastive, causal for captioning). Configs use
mammut_*(legacy) ormammut2_*(corrected defaults). - CoCa v2: Configured via
coca2_*. Features attentional pooling (vision_cfg.attnotional_pool="cascade") and corrected CLS/pad attention masks (text_cfg.correct_cls_mask=true). - Hugging Face ModernBERT: Support for text towers like
gte-modernbert-base-ViT-B-32-256.
- NaFlex CLIP/CLAP/GenLIP/GenLAP: Supports variable-resolution/aspect image towers (timm
Perform model distillation
mainYou can distill knowledge from a pre-trained model into a new model by using the--distill-modeland--distill-pretrainedflags. For example, to distill from OpenAI's ViT-L/14, use--distill-model ViT-L-14 --distill-pretrained openai.Use the legacy training entry point for older scripts
mainIf you have existing image/text training scripts that rely on the pre-task loop (e.g., calling
train_one_epochdirectly), you can use the compatibility shim:python -m open_clip_train.legacy_mainLimitations of
legacy_main:- Does not support FSDP2, EMA, CLAP audio training, NaFlex, or length bucketing.
- Uses a frozen decode-first data pipeline.
- Should be treated as a compatibility shim rather than a path for new development.
Train CLIP with Hugging Face text encoders
mainYou can use different language models as the text encoder by specifying a Hugging Face model config via the
--modelparameter and providing the tokenizer via--hf-tokenizer-name. You can also partially freeze the text encoder using--lock-textand--lock-text-unlocked-layers <N>, where<N>is the number of layers from the end to leave unfrozen.python -m open_clip_train.main \ --train-data="pipe:aws s3 cp s3://s-mas/cc3m/{00000..00329}.tar -" \ --train-num-samples 3000000 \ --val-data="pipe:aws s3 cp s3://s-mas/cc3m/{00330..00331}.tar -" \ --dataset-type webdataset \ --batch-size 256 \ --warmup 2000 \ --epochs 10 \ --lr 5e-4 \ --precision amp \ --workers 6 \ --model "roberta-ViT-B-32" \ --lock-text \ --lock-text-unlocked-layers 10 \ --name "10_unfrozen" \ --report-to "tensorboard"Fine-tune CoCa models
mainTo fine-tune CoCa models (e.g., on MSCOCO), use the
open_clip_train.mainscript. To focus specifically on the generative side rather than the contrastive side, set--coca-contrastive-loss-weight 0and--coca-caption-loss-weight 1.python -m open_clip_train.main \ --dataset-type "csv" \ --train-data "path/to/data/dir/train2014.csv" \ --warmup 1000 \ --batch-size 128 \ --lr 1e-5 \ --wd 0.1 \ --epochs 1 \ --workers 3 \ --model "coca_ViT-L-14" \ --report-to "wandb" \ --coca-contrastive-loss-weight 0 \ --coca-caption-loss-weight 1 \ --log-every-n-steps 100Use LAION-400M pretrained models
mainLAION-400M models were trained to replicate OpenAI's ViT results using the LAION-400M dataset. Available architectures include:
- ViT-B/32 224x224: Top-1 ImageNet-1k zero-shot accuracy of 62.96%.
- ViT-B/16 224x224: Top-1 ImageNet-1k zero-shot accuracy of 67.07%.
- ViT-B/16+ 240x240: Increased vision width (896), text width (640), and resolution (240x240). Top-1 ImageNet-1k zero-shot accuracy of 69.21%.
- ViT-L/14 224x224: Top-1 ImageNet-1k zero-shot accuracy of 72.77%.
Trained weights can be found in release v0.2.
Implement Int8 inference quantization
mainOpenCLIP provides beta support for Int8 inference using
bitsandbytes.nn.Linear8bitLt. This primarily targets the MLP linear layers (c_fcandc_proj) to reduce memory usage by roughly 2x, with minimal accuracy impact.Workflow:
- Create the model and transforms using
open_clip.create_model_and_transforms. - Use
open_clip.utils.replace_linearto swapnn.Linearmodules with the Int8 implementation. Specify the modules to include viainclude_modules=['c_fc', 'c_proj']. - Call
open_clip.utils.convert_int8_model_to_inference_mode(int8_model)to finalize the quantization.
Saving and Loading: Because
replace_linearmodifies the model in place, astate_dictsaved from a quantized model can only be loaded back into a model that has already had its linear layers swapped.- To Save: Build model $\rightarrow$
replace_linear$\rightarrow$torch.save(state_dict). - To Load: Rebuild architecture $\rightarrow$
replace_linear$\rightarrow$convert_int8_model_to_inference_mode$\rightarrow$load_state_dict.
from functools import partial import bitsandbytes as bnb import open_clip model, _, preprocess = open_clip.create_model_and_transforms('ViT-B-32', pretrained='laion2b_s34b_b79k') model = model.half() int8_linear_layer = partial(bnb.nn.Linear8bitLt, has_fp16_weights=False) int8_model = open_clip.utils.replace_linear(model, int8_linear_layer, include_modules=['c_fc', 'c_proj']).cuda() open_clip.utils.convert_int8_model_to_inference_mode(int8_model)- Create the model and transforms using