Two ways to use it
Both are supported paths, not a main one and a fallback. They are the same API.
The base install is an HTTP client. It has no torch, no transformers and no weights,
and everything works through it: asking, embedding, and training, since the
encoder that fits the head lives on the server.
jev encoders works offline, and
jev ask/train/heads/rm --url ... (or $JEV_URL, with $JEV_API_KEY) drive a server
from the command line.
jevimage.load() in that install does not fail obscurely; it names both fixes:
pip install 'jevimage[serve]' adds fastapi and uvicorn so you can
be the server other people connect to: jev serve. See Serving.
60 seconds
Against a server, needing nothing butpip install jevimage:
Answer is a dict subclass with attribute access, so
answers["colour"] prints as that short repr, a.choice and a["choice"] are the same
thing, and json.dumps(answers) gives you the full shape with no conversion step.
To run the encoder in your own process instead, change the connect line to
jevimage.load() and the rest of the file stands. The two produce the same objects; the
numbers match when both sides run the same encoder, because what the probabilities depend
on is the encoder, not which side of the wire it runs on.
The numbers above came from a deterministic stand-in encoder, so the transcript is reproducible and costs nothing to re-run:python examples/make_fixtures.pywrites theds/squares it asks about, and the server was the toy one from Serving (a custom encoder has to be served from Python -jev serveonly knows the built-in registry). The shapes, the repr and the code are real. How peaked a real distribution is depends on the question and the encoder’s temperature: the same two-option question onsiglip2-base-224measured{'red': 0.997553, 'blue': 0.002447}(also saturated), while a three-levelscoreon the same image came out{0: 0.195, 1: 0.094, 2: 0.711}. Saturation is the encoder’s doing, not the library’s; see Choosing an encoder.
What it does not do
- No generation. There is no text output, no captioning, no VQA in free text. If you need a sentence, this is the wrong tool; if you need a number you can threshold, it is the right one.
- No detection, no boxes, no segmentation. Answers are about the whole image. “Is there a bicycle” is a question it can answer; “where is the bicycle” is not.
- No OCR. Text in the image is whatever the encoder made of it, which is not reading.
- No comparison across images.
ask()answers about one image. Handed a list, a localJevand aconnect()client refuse with the same sentence:TypeError: ask() takes one image, got a list of 2. Loop over them, or call embed() once and ask_embedding() per row.Pass one image, and useembed()if you want the vectors for several. (compare()is unrelated: it compares a trained head against zero-shot prompts, not one image against another.) - No open-ended questions. You supply the options. A
choicewith an option missing returns a confident answer among the options you gave, because the probabilities are over your list and nothing else.
Where to go next
Install →