Kılavuzlar
Eğitim: denetimler ve onları gören bir hakemle görüntüler
Görüntü üreten bir fonksiyonu, burada bir başlık da yazan bir ürün küçük resim oluşturucusunu, değerlendirin. Küçük resimleri model gerektirmeyen ölçümlerle denetleyin, başlıkları her küçük resmi gören bir modelle değerlendirin, o hakemi bir kişiye karşı ölçün, sonra gerçek bir değişikliği yayına alın. Her adım bu makinede model ve ağ olmadan çalışır; isteğe bağlı bir adım ise yerine gerçek bir görsel model koyar.
Ne oluşturacaksınız
Bir katalog hizmeti bir ürün fotoğrafı alır, bir küçük resim kaydeder ve ürünün rengini adlandıran tek satırlık bir başlık yazar. Bir sürümün yayına alınıp alınamayacağına üç soru karar verir:
- Her küçük resim kataloğa uyuyor mu: bir web biçimi, en fazla 256'ya 256 piksel, en fazla 50 kB? Bu bir ölçümdür ve media_check tarafından küçük resmin baytlarından yapılır.
- Her küçük resim hâlâ ürünün fotoğrafı mı, boş bir görüntü, bir kırpıntı ya da başka bir ürün değil mi? image_matches_reference onu algısal hash ile fotoğrafla karşılaştırır.
- Her başlık, bir alışverişçinin gördüğü rengi adlandırıyor mu? Bu göz gerektirir, bu yüzden bir rubrik hakemine küçük resim gösterilir.
Fotoğraflar ve küçük resimler proje klasöründe kalır. Sistem onları başvuruyla kaydeder (media/v1): her dosyanın nerede olduğu, türü, boyutu ve sha256 değeri. Vaka, çalıştırma, hakem ve kapı gibi terimler Kavramlar sayfasında tanımlanmıştır; medya hakkındaki her şey Görüntü, ses ve video sayfasındadır.
Ön koşullar
- Python 3.11 veya üstü ve görüntüleri karşılaştırmak için Pillow ekleyen medya ekiyle Oloproof:
python3 -m venv .venv
. .venv/bin/activate
pip install 'oloproof[media]'- Paketle birlikte gelen örnek proje. Onu yeni bir dizine kopyalayın ve orada çalışın:
oloproof init --example media product-thumbnails
cd product-thumbnails- Yedek hakem için boş bir 8798 portu (değilse iki yerde de değiştirin).
"İsteğe bağlı: gerçek bir görsel model" bölümüne kadarki her adım çevrimdışı ve deterministiktir: API anahtarı yok, sağlayıcı hesabı yok, maliyet yok.
Dosyalar
product-thumbnails/
app.py the thumbnailer under test (baseline)
app_v2.py the candidate change
judge_server.py a stand-in vision judge speaking the OpenAI API on 127.0.0.1
rubrics/caption_names_colour.md the judge's rubric
oloproof.yaml the suite
release.yaml rules for a run
compare.yaml a rule for a comparison
data/products.jsonl 20 cases
photos/ the 20 product photos the cases name
make_photos.py how the photos were drawn
labels/reviewer_verdicts.csv one person's verdicts on the baseline's captions
fill_labels.py copies those verdicts into a labelling sheetHer komutu product-thumbnails/ içinden çalıştırın.
Uygulama görüntülerini kaydeder
# app.py (excerpt)
@system(name="thumbnailer", version=VERSION, records=("media/v1",))
def describe(case: dict[str, Any]) -> dict[str, str]:
photo_path = HERE / case["photo"]
photo = Image.open(photo_path).convert("RGB")
thumb = photo.copy()
thumb.thumbnail((320, 320))
out = HERE / "thumbs" / VERSION / photo_path.name
out.parent.mkdir(parents=True, exist_ok=True)
thumb.save(out)
given = media_file(photo_path, role="input")
made = media_file(out, width=thumb.width, height=thumb.height)
current_case().media([given, made])
centre = photo.getpixel((photo.width // 2, photo.height // 2))
return {"caption": f"A {colour_name(centre)} product."}media_file(path) bir dosyayı tanımlar: file:// konumu, MIME türü, boyutu ve sha256 değeri, dosyanın adıyla adlandırılmış olarak. role="input" sistemin aldığı fotoğrafı işaretler; küçük resim bir çıktıdır, varsayılan da budur. current_case().media(...) ikisini tek bir media/v1 yapıtı olarak kaydeder ve oloproof.yaml içindeki records: [media/v1] sistemin onu kaydettiğini bildirir. Hiçbir şey kopyalanmaz: bir denetim ya da bir hakem her dosyayı sonradan yeniden okur ve baytları artık kayıtla eşleşmeyen bir dosyayı reddeder.
Bu temelin iki kusuru var. Küçük resimleri 320 piksel genişliğindedir ve başlığı fotoğrafın ortadaki pikselinin rengini adlandırır; ürün bir kenarda durduğunda bu piksel arka plandır. Her sürüm küçük resimlerini thumbs/<version>/ altına yazar, bu yüzden sonraki bir çalıştırma daha önceki bir çalıştırmanın kaydettiği dosyaların üzerine asla yazmaz.
Veri kümesi
{"id": "p03", "input": {"photo": "photos/p03.png"}, "expected": {"photo": "photos/p03.png", "colour": "yellow", "shape": "triangle"}}input sistemin aldığı şeydir. expected.photo küçük resmin karşılaştırıldığı referanstır; colour ve shape vakayı okuyan bir kişi için oradadır ve hiçbir değerlendirici onları okumaz.
Değerlendiricileri seçme
evaluators:
# The catalogue's limits, measured from the thumbnail's bytes: a web format, at most 256 by
# 256 pixels, at most 50 kB.
- type: media_check
criterion: thumbnail_fits
kind: image
formats: [png, jpeg, webp]
max_width: 256
max_height: 256
max_bytes: 50000
# The thumbnail is still the product's photo: a perceptual hash within 10 of 64 bits.
- type: image_matches_reference
criterion: same_photo
reference_field: photo
max_distance: 10
# The caption, judged by a model that sees the thumbnail.
- type: rubric_judge
criterion: caption_names_colour
provider: openai_compatible
model: stand-in-vision
base_url: http://127.0.0.1:8798/v1
rubric_file: rubrics/caption_names_colour.md
media: outputmedia_check her çıktı görüntüsünü ölçer: biçimi ilk baytlarından, boyutu başlığından, asla sistemin bildirdiğinden değil. image_matches_reference küçük resmin ve expected.photo değerinin adlandırdığı fotoğrafın hash'ini alır ve hash'ler 64 bitlerinin en fazla 10'unda farklı olduğunda geçer; yeniden boyutlandırma ya da yeniden sıkıştırma bir hash'i birkaç bit oynatır, başka bir resim çok bit oynatır. İkisi de model çağırmaz, bu yüzden ikisi de ilk çalıştırmadan itibaren karar verir.
media: output vakanın çıktı görüntülerini hakemin isteğine ekler, her biri isteminde adlandırılmış olarak. Bir hakem, insanların etiketleri onlarla uyuştuğunu gösterene kadar hiçbir şeye karar vermez, bu yüzden üçüncü kural bunu bekler.
Yedek hakem
Bir rubrik hakemi istemini ve eklenen görüntüleri bir modele gönderir ve {"pass": true|false, "rationale": "..."} geri okur. Burada model, aynı API'yi 127.0.0.1 üzerinde konuşan ve bir model olmayan judge_server.py dosyasıdır: eklenen küçük resmin kodunu çözer, arka planın beyazı ve grisi dışındaki en yaygın rengini bulur ve onu adlandıran bir başlığı geçirir. Onu ikinci bir terminalde başlatın ve çalışır halde bırakın:
python judge_server.py --port 8798Politika
version: 1
confidence_level: 0.95
block_on: [FAIL, INSUFFICIENT_EVIDENCE, MANUAL_REVIEW]
require_validated_evaluators: true
rules:
- id: thumbnails-fit
metric: thumbnail_fits
kind: observed_count
max_failures: 0
- id: same-photo
metric: same_photo
kind: observed_count
max_failures: 0
- id: caption-floor
metric: caption_names_colour
min: 0.80Her küçük resim uymalı ve kendi fotoğrafı olmalıdır. Başlıkların en az %80'i doğru rengi adlandırmalıdır; bu, yalnızca aralığın alt sınırı %80'i aştığında karara bağlanır.
Çalıştırın
oloproof runGate: BLOCK (exit 1)
│ thumbnails-fit │ thumbnail_fits │ FAIL │ observed_failures_exceed_limit │
│ same-photo │ same_photo │ PASS │ observed_failures_within_limit │
│ caption-floor │ caption_names_colour │ INSUFFICIENT_EVIDENCE │ evaluator_not_validated │
│ thumbnail_fits │ 0.0% │ [0.0%, 16.9%] │ 0 / 20 observed · 0 missing · 0 excluded │
│ same_photo │ 100.0% │ [83.1%, 100.0%] │ 20 / 20 observed · 0 missing · 0 excluded │
│ caption_names_colour │ 60.0% │ [36.0%, 80.9%] │ 12 / 20 observed · 0 missing · 0 excluded │Hiçbir küçük resim uymuyor, her küçük resim kendi fotoğrafı ve 20 başlıktan 12'si doğru rengi adlandırıyor. Hakemin kuralı karara bağlanmamıştır, çünkü hakemi henüz kimse ölçmedi.
Başarısızlıkları inceleyin
oloproof inspect RUN_ID --failuresp03
output: {"caption": "A white product."}
thumbnail_fits: failed
measured: p03.png: width 320 px is above 256 px
caption_names_colour: failed
judge text, not verified: the product is yellow; the caption says 'a white product.'Bir denetimin gerekçesi measured olarak işaretlenmiş bir ölçümdür; bir hakeminki ise kimsenin denetlemediği kendi sözleridir. Fotoğraflar ve küçük resimler, oloproof export RUN_ID sonrasında, çalışma tezgâhında vakanın sayfasında her hükmün yanında da görünür ve bu klasörden okunur; barındırılan bir çalışma alanı onları tarayıcınızın oloproof collect üzerinden getirmesini sağlar ve onları asla tutmaz (Görüntü, ses ve video).
Hakemi bir kişiye karşı ölçün
Çalıştırmanın vakalarından rastgele bir örneklemi, hakemin hükümleri olmadan bir sayfaya çekin, bir kişinin her küçük resme ve başlığa bakmasını sağlayın ve söylediklerini içe aktarın. Burada fill_labels.py o kişinin yerini tutar ve onun hükümlerini labels/reviewer_verdicts.csv dosyasından kopyalar:
oloproof labels export RUN_ID --criterion caption_names_colour --sample 20 --local --out sample.csv
python fill_labels.py sample.csv
oloproof labels import sample.csvSonra hakemi bu etiketlere karşı ölçün ve bunu kimin yaptığını kaydedin:
oloproof evaluators list
oloproof evaluators validate EVALUATOR_ID --by alicecaption_names_colour: sha256:53605dd6... is now VALIDATED
agreement 100.0% [83.1%, 100.0%] · 20 of 20 labelled cases agreed · 0 labelled but not judged · kappa 1.000Görüntüleri gören bir hakem, tıpkı metin okuyan bir hakem gibi ölçülür. Barındırılan bir çalışma alanında inceleme kuyruğu, her vakanın görüntülerini inceleyiciye gösterir; görüntüleri inceleyicinin tarayıcısı toplayıcınızdan getirir (Hakemler).
oloproof gate RUN_ID --policy release.yamlthumbnails-fit: FAIL (observed_failures_exceed_limit)
same-photo: PASS (observed_failures_within_limit)
caption-floor: INSUFFICIENT_EVIDENCE (interval_overlaps_threshold)
Gate: BLOCK (exit 1)Hakem artık karar verebilir ve %60 yeterli değildir.
Gerçek bir değişiklik yapın
app_v2.py 256 piksellik küçük resimler üretir ve ürün nerede olursa olsun fotoğrafın arka plan dışındaki en yaygın rengini adlandırır. Onu app.py üzerine kopyalayın, oloproof.yaml içinde system altında version: main-colour ayarlayın, hakemi çalışır halde tutun ve:
oloproof runGate: ALLOW (exit 0)
│ thumbnails-fit │ thumbnail_fits │ PASS │ observed_failures_within_limit │
│ same-photo │ same_photo │ PASS │ observed_failures_within_limit │
│ caption-floor │ caption_names_colour │ PASS │ lower_bound_meets_minimum │Hakem, doğrulanmış olanla aynı değerlendirici sürümüdür, bu yüzden hükümleri sayılır.
Adayı temelle karşılaştırın
oloproof compare CANDIDATE_RUN_ID BASELINE_RUN_ID --policy compare.yamlthumbnail_fits: +100.0 points [+52.9, +100.0] · 20 paired · 0 missing · 0 excluded
caption_names_colour: +40.0 points [+1.8, +72.7] · 20 paired · 0 missing · 0 excluded
captions-better caption_names_colour superiority PASS difference_above_zeroİsteğe bağlı: gerçek bir görsel model
Bu adım çevrimdışı yoldan ayrılır. Görüntüleri okuyan bir model gerektirir: yerelde, bir görsel modelle Ollama (ollama pull qwen2.5vl), anahtarsız ve maliyetsiz; bulutta, api_key_env ile provider: anthropic ya da openai, her kelime gibi her görüntü için de faturalanır.
# live_judge.yaml
type: rubric_judge
criterion: caption_names_colour
provider: openai_compatible
model: qwen2.5vl
base_url: http://localhost:11434/v1
rubric_file: rubrics/caption_names_colour.md
media: output
timeout_s: 300oloproof evaluators try live_judge.yamlBu, inceleyicinizin etiketlediği vakaları gerçek modelle değerlendirir ve onu benimsemeden uyumunu bildirir. Onu benimsemek için oloproof.yaml içinde yedeğin yerine koyun: yeni bir model yeni bir değerlendirici sürümüdür, bu yüzden onu yukarıdaki gibi etiketlere karşı doğrulayın.
Sorun giderme
| Belirti | Neden ve çözüm |
|---|---|
| caption_names_colour tamamen eksik | Hakem sunucusu çalışmıyor ya da base_url üzerinde değil; oloproof inspect RUN_ID --failures nedenini gösterir. |
| image_matches_reference Pillow'u adlandırarak çalıştırmayı durduruyor | Medya ekini kurun: pip install 'oloproof[media]'. |
| Bir vaka media_unavailable ile eksik | Kaydedilen bir dosya çalıştırmadan sonra taşındı ya da silindi. Bir çalıştırmanın kaydettiği dosyaları, çalıştırmayı tuttuğunuz sürece tutun. |
| Bir çalıştırma is not the recorded content ile duruyor | Kaydedilen bir dosya çalıştırmadan sonra değiştirildi. Bir denetim ya da hakem farklı baytları asla kaydedilmiş olanlar gibi okumaz; her sürümün dosyalarını kendi yerine yazın. |
| Doğruladıktan sonra evaluator_not_validated | Hakemi (model, uç nokta, port, rubrik, media) değiştirdiniz ve yeni bir sürüm oluşturdunuz. Onu doğrulayın. |
Sınırlamalar
- Yedek hakem pikselleri sayar. Değerlendirme kalitesini değil, iş akışını gösterir.
- Algısal hash rengi değil, yerleşimi ve ışığı okur: fotoğrafın bir küçük resmini boş bir görüntüden ya da farklı bir sahneden ayırır, ama aynı stüdyodaki bir ürünü bir başkasından ayırmaz. Geniş boş alanları olan düz grafikler onu fotoğraflardan daha çok oynatır.
- Yirmi etiket geniş bir uyum aralığı verir. Güvendiğiniz bir hakem için rastgele ve kör olarak daha fazla etiketleyin.
- Ses ve video başka ayarlarla aynı şekilde çalışır: bkz. Görüntü, ses ve video.