diff --git a/.gitignore b/.gitignore index 86e4398..321f181 100644 --- a/.gitignore +++ b/.gitignore @@ -1,139 +1,10 @@ -Example.ipynb - -# Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class - -# C extensions -*.so - -# Distribution / packaging -.Python -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -wheels/ -pip-wheel-metadata/ -share/python-wheels/ -*.egg-info/ -.installed.cfg -*.egg -MANIFEST - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.nox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*.cover -*.py,cover -.hypothesis/ -.pytest_cache/ - -# Translations -*.mo -*.pot - -# Django stuff: -*.log -local_settings.py -db.sqlite3 -db.sqlite3-journal - -# Flask stuff: -instance/ -.webassets-cache - -# Scrapy stuff: -.scrapy - -# Sphinx documentation -docs/_build/ -_build/ - -# PyBuilder -target/ - -# Jupyter Notebook +*.egg-info +.pytest_cache .ipynb_checkpoints -# IPython -profile_default/ -ipython_config.py - -# pyenv -.python-version - -# pipenv -# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. -# However, in case of collaboration, if having platform-specific dependencies or dependencies -# having no cross-platform support, pipenv may install dependencies that don't work, or not -# install all needed dependencies. -#Pipfile.lock - -# PEP 582; used by e.g. github.com/David-OConnor/pyflow -__pypackages__/ - -# Celery stuff -celerybeat-schedule -celerybeat.pid - -# SageMath parsed files -*.sage.py - -# Environments -.env -.venv -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ - -# Spyder project settings -.spyderproject -.spyproject - -# Rope project settings -.ropeproject - -# mkdocs documentation -/site - -# mypy -.mypy_cache/ -.dmypy.json -dmypy.json - -# Pyre type checker -.pyre/ - -# Ignore doctrees -.doctrees/ -doctrees/ -docsrc/_build/* -docs/*.ipynb -docsrc/*.ipynb +thumbs.db +.DS_Store +.idea diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index dde9080..0000000 --- a/MANIFEST.in +++ /dev/null @@ -1,2 +0,0 @@ -include LICENSE -include clip/bpe_simple_vocab_16e6.txt.gz diff --git a/README.md b/README.md index 033e00e..0a9cb4f 100644 --- a/README.md +++ b/README.md @@ -14,14 +14,15 @@ CLIP (Contrastive Language-Image Pre-Training) is a neural network trained on a ## Usage +First, [install PyTorch 1.7.1](https://pytorch.org/get-started/locally/) and torchvision, as well as small additional dependencies. On a CUDA GPU machine, the following will do the trick: + ```bash -$ pip install clip-by-openai -``` -Or if you want cuda installation: -```bash -$ pip install clip-by-openai[cuda] +$ conda install --yes -c pytorch pytorch=1.7.1 torchvision cudatoolkit=11.0 +$ pip install ftfy regex tqdm ``` +Replace `cudatoolkit=11.0` above with the appropriate CUDA version on your machine or `cpuonly` when installing on a machine without a GPU. + ```python import torch import clip diff --git a/clip/clip.py b/clip/clip.py index 7459ac4..e4640e5 100644 --- a/clip/clip.py +++ b/clip/clip.py @@ -75,6 +75,8 @@ def load(name: str, device: Union[str, torch.device] = "cuda" if torch.cuda.is_a if not jit: model = build_model(model.state_dict()).to(device) + if device == "cpu": + model.float() return model, transform # patch the device names diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..289ca08 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,5 @@ +ftfy +regex +tqdm +torch>=1.7.1,<1.7.2 +torchvision==0.8.2 diff --git a/setup.py b/setup.py index 15684ef..05946b1 100644 --- a/setup.py +++ b/setup.py @@ -1,58 +1,24 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - import os + +import pkg_resources from setuptools import setup, find_packages from pathlib import Path -core_req = ['ftfy', 'regex', 'tqdm', 'torch==1.7.1', 'torchvision==0.8.2'] -extras_require={ - 'cuda': ['cudatoolkit==11.0'], - 'dev': ['pytest'] -} -package_data = [str(x) for x in list(Path('clip').rglob("*.gz"))] -package_data.extend([str(x) for x in list(Path('clip').rglob("*.md"))]) setup( - name='clip_by_openai', - version='0.1.1.3', + name="clip", + py_modules=["clip"], + version="1.0", + description="", author="OpenAI", - author_email="", - description="CLIP by OpenAI", - long_description=open("README.md", "r", encoding="utf-8").read(), - long_description_content_type="text/markdown", - keywords="vector, embeddings, machinelearning, ai, artificialintelligence, nlp, pytorch, nearestneighbors, search, analytics, clustering, dimensionalityreduction", - license="MIT", packages=find_packages(exclude=["tests*"]), - package_data={'clip': package_data}, - include_package_data=True, - python_requires=">=3", - install_requires=core_req, - extras_require=extras_require, - classifiers=[ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Intended Audience :: Education", - "Intended Audience :: Science/Research", - "Intended Audience :: Information Technology", - "Intended Audience :: Financial and Insurance Industry", - "License :: OSI Approved :: Apache Software License", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.4", - "Programming Language :: Python :: 3.5", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Database", - "Topic :: Internet :: WWW/HTTP :: Indexing/Search", - "Topic :: Multimedia :: Sound/Audio :: Conversion", - "Topic :: Multimedia :: Video :: Conversion", - "Topic :: Scientific/Engineering :: Artificial Intelligence", - "Topic :: Scientific/Engineering :: Image Recognition", - "Topic :: Scientific/Engineering :: Information Analysis", - "Topic :: Scientific/Engineering :: Visualization", - "Topic :: Software Development :: Libraries :: Application Frameworks", + package_data={'clip': [str(x) for x in list(Path('clip').rglob("*.gz"))]}, + install_requires=[ + str(r) + for r in pkg_resources.parse_requirements( + open(os.path.join(os.path.dirname(__file__), "requirements.txt")) + ) ], + include_package_data=True, + extras_require={'dev': ['pytest']}, ) diff --git a/tests/test_consistency.py b/tests/test_consistency.py new file mode 100644 index 0000000..29d343d --- /dev/null +++ b/tests/test_consistency.py @@ -0,0 +1,25 @@ +import numpy as np +import pytest +import torch +from PIL import Image + +import clip + + +@pytest.mark.parametrize('model_name', clip.available_models()) +def test_consistency(model_name): + device = "cpu" + jit_model, transform = clip.load(model_name, device=device) + py_model, _ = clip.load(model_name, device=device, jit=False) + + image = transform(Image.open("CLIP.png")).unsqueeze(0).to(device) + text = clip.tokenize(["a diagram", "a dog", "a cat"]).to(device) + + with torch.no_grad(): + logits_per_image, _ = jit_model(image, text) + jit_probs = logits_per_image.softmax(dim=-1).cpu().numpy() + + logits_per_image, _ = py_model(image, text) + py_probs = logits_per_image.softmax(dim=-1).cpu().numpy() + + assert np.allclose(jit_probs, py_probs, atol=0.01, rtol=0.1) diff --git a/tests/test_encode.py b/tests/test_encode.py deleted file mode 100644 index f07e3ee..0000000 --- a/tests/test_encode.py +++ /dev/null @@ -1,16 +0,0 @@ -import clip -import torch -import torch -from PIL import Image -def test_smoke_simple_cpu(): - device = 'cpu' - model, preprocess = clip.load("ViT-B/32", device=device) - image = preprocess(Image.open('CLIP.png')).unsqueeze(0).to(device) - text = clip.tokenize(["a diagram", "a dog", "a cat"]).to(device) - with torch.no_grad(): - model.encode_image(image) - model.encode_text(text) - logits_per_image, logits_per_text = model(image, text) - probs = logits_per_image.softmax(dim=-1).cpu().numpy() - assert True -