{"version":2,"relationshipURLBase":"https://codingai-lec03.pages.dev/course/notebook-blocks/aaa45a4607af423da4c9144dad703b56.html","relationshipResolution":"Resolve relative relationship URLs against relationshipURLBase; complete records and absolute URLs are in blocks.","title":"2 · 独立准备并核对预处理 · 实现代码","url":"https://codingai-lec03.pages.dev/course/notebook-blocks/aaa45a4607af423da4c9144dad703b56.html","markdown":"https://codingai-lec03.pages.dev/course/notebook-blocks/aaa45a4607af423da4c9144dad703b56.md","pages":[{"id":"reading-opening","title":"2 · 独立准备并核对预处理 · 实现代码","unit":"2 · 独立准备并核对预处理 · 实现代码","unitId":"notebook-blocks/aaa45a4607af423da4c9144dad703b56","chapter":"course","number":1}],"aliases":[{"oldId":"b-4c9905e74e5444df2a75ff0f","targetId":"b-4c9905e74e5444df2a75ff0f","page":"reading-opening","operation":"move","beforeSHA256":"b097cc692a4f43c3eeba08ce9c2e73c631f1bad298a5fb1dec9efa967315dac3","afterSHA256":"b097cc692a4f43c3eeba08ce9c2e73c631f1bad298a5fb1dec9efa967315dac3","reason":"Same source body in authored semantic page"},{"oldId":"b-ebccbdbf54a9b6c5bf33b89b","targetId":"b-ebccbdbf54a9b6c5bf33b89b","page":"reading-opening","operation":"move","beforeSHA256":"7baa191559eacb8275b1e0461ad77dcebff0283b63c353ab9861bdfaf4f94a91","afterSHA256":"7baa191559eacb8275b1e0461ad77dcebff0283b63c353ab9861bdfaf4f94a91","reason":"Same source body in authored semantic page"},{"oldId":"b-182d56c92f0ce35049e09245","targetId":"b-182d56c92f0ce35049e09245","page":"reading-opening","operation":"move","beforeSHA256":"42cba31deccba2a350b9b23bd0ca1dcaa4c4c5cb9d35c773e1fcb89124788ccd","afterSHA256":"42cba31deccba2a350b9b23bd0ca1dcaa4c4c5cb9d35c773e1fcb89124788ccd","reason":"Same source body in authored semantic page"},{"oldId":"b-0cc71f98f2ef9d93bcfd7f9d","targetId":"b-0cc71f98f2ef9d93bcfd7f9d","page":"reading-opening","operation":"move","beforeSHA256":"90e8ba62b9af4bedd5be3a2559568519f4df7a42b13048f81039496efd45dea2","afterSHA256":"90e8ba62b9af4bedd5be3a2559568519f4df7a42b13048f81039496efd45dea2","reason":"Same source body in authored semantic page"},{"oldId":"b-683f23b8f9963856d210b2dd","targetId":"b-683f23b8f9963856d210b2dd","page":"reading-opening","operation":"move","beforeSHA256":"b49cd167f2cd93fe7431aea28959a8acf1559bfe30fb63d65ca0078b3ba9b785","afterSHA256":"b49cd167f2cd93fe7431aea28959a8acf1559bfe30fb63d65ca0078b3ba9b785","reason":"Same source body in authored semantic page"}],"blocks":[{"id":"b-4c9905e74e5444df2a75ff0f","type":"p","scope":"document","url":"https://codingai-lec03.pages.dev/course/notebook-blocks/aaa45a4607af423da4c9144dad703b56.html#b-4c9905e74e5444df2a75ff0f","content":"[LAB 04 · CLIP：候选、提示与关系检验](/course/notebooks/0ba963931ddf4866b507b210d93a43bf.html)","sha256":"b097cc692a4f43c3eeba08ce9c2e73c631f1bad298a5fb1dec9efa967315dac3","chapter":{"id":"course","title":"2 · 独立准备并核对预处理 · 实现代码"},"unit":{"id":"notebook-blocks/aaa45a4607af423da4c9144dad703b56","title":"2 · 独立准备并核对预处理 · 实现代码"},"page":{"id":"reading-opening","title":"2 · 独立准备并核对预处理 · 实现代码","number":1},"sectionTitle":"2 · 独立准备并核对预处理 · 实现代码","currentQuestion":"2 · 独立准备并核对预处理 · 实现代码","sourceSlides":[],"knowledgeBlock":null,"formulas":[],"previousBlock":null,"nextBlock":"b-ebccbdbf54a9b6c5bf33b89b","prerequisites":[],"relatedBlocks":[]},{"id":"b-ebccbdbf54a9b6c5bf33b89b","type":"h1","scope":"document","url":"https://codingai-lec03.pages.dev/course/notebook-blocks/aaa45a4607af423da4c9144dad703b56.html#b-ebccbdbf54a9b6c5bf33b89b","content":"# 2 · 独立准备并核对预处理 · 实现代码","sha256":"7baa191559eacb8275b1e0461ad77dcebff0283b63c353ab9861bdfaf4f94a91","chapter":{"id":"course","title":"2 · 独立准备并核对预处理 · 实现代码"},"unit":{"id":"notebook-blocks/aaa45a4607af423da4c9144dad703b56","title":"2 · 独立准备并核对预处理 · 实现代码"},"page":{"id":"reading-opening","title":"2 · 独立准备并核对预处理 · 实现代码","number":1},"sectionTitle":"2 · 独立准备并核对预处理 · 实现代码","currentQuestion":"2 · 独立准备并核对预处理 · 实现代码","sourceSlides":[],"knowledgeBlock":null,"formulas":[],"previousBlock":"b-4c9905e74e5444df2a75ff0f","nextBlock":"b-182d56c92f0ce35049e09245","prerequisites":[{"id":"b-4c9905e74e5444df2a75ff0f","url":"#b-4c9905e74e5444df2a75ff0f","role":"problem-context"}],"relatedBlocks":[]},{"id":"b-182d56c92f0ce35049e09245","type":"p","scope":"document","url":"https://codingai-lec03.pages.dev/course/notebook-blocks/aaa45a4607af423da4c9144dad703b56.html#b-182d56c92f0ce35049e09245","content":"主线阅读与优先实验","sha256":"42cba31deccba2a350b9b23bd0ca1dcaa4c4c5cb9d35c773e1fcb89124788ccd","chapter":{"id":"course","title":"2 · 独立准备并核对预处理 · 实现代码"},"unit":{"id":"notebook-blocks/aaa45a4607af423da4c9144dad703b56","title":"2 · 独立准备并核对预处理 · 实现代码"},"page":{"id":"reading-opening","title":"2 · 独立准备并核对预处理 · 实现代码","number":1},"sectionTitle":"2 · 独立准备并核对预处理 · 实现代码","currentQuestion":"2 · 独立准备并核对预处理 · 实现代码","sourceSlides":[],"knowledgeBlock":null,"formulas":[],"previousBlock":"b-ebccbdbf54a9b6c5bf33b89b","nextBlock":"b-0cc71f98f2ef9d93bcfd7f9d","prerequisites":[{"id":"b-ebccbdbf54a9b6c5bf33b89b","url":"#b-ebccbdbf54a9b6c5bf33b89b","role":"section-title"},{"id":"b-4c9905e74e5444df2a75ff0f","url":"#b-4c9905e74e5444df2a75ff0f","role":"problem-context"}],"relatedBlocks":[]},{"id":"b-0cc71f98f2ef9d93bcfd7f9d","type":"p","scope":"document","url":"https://codingai-lec03.pages.dev/course/notebook-blocks/aaa45a4607af423da4c9144dad703b56.html#b-0cc71f98f2ef9d93bcfd7f9d","content":"真实CLIP输入/权重/分数、候选改动、四条件规则与独立关系推理","sha256":"90e8ba62b9af4bedd5be3a2559568519f4df7a42b13048f81039496efd45dea2","chapter":{"id":"course","title":"2 · 独立准备并核对预处理 · 实现代码"},"unit":{"id":"notebook-blocks/aaa45a4607af423da4c9144dad703b56","title":"2 · 独立准备并核对预处理 · 实现代码"},"page":{"id":"reading-opening","title":"2 · 独立准备并核对预处理 · 实现代码","number":1},"sectionTitle":"2 · 独立准备并核对预处理 · 实现代码","currentQuestion":"2 · 独立准备并核对预处理 · 实现代码","sourceSlides":[],"knowledgeBlock":null,"formulas":[],"previousBlock":"b-182d56c92f0ce35049e09245","nextBlock":"b-683f23b8f9963856d210b2dd","prerequisites":[{"id":"b-ebccbdbf54a9b6c5bf33b89b","url":"#b-ebccbdbf54a9b6c5bf33b89b","role":"section-title"},{"id":"b-4c9905e74e5444df2a75ff0f","url":"#b-4c9905e74e5444df2a75ff0f","role":"problem-context"}],"relatedBlocks":[]},{"id":"b-683f23b8f9963856d210b2dd","type":"pre","scope":"document","url":"https://codingai-lec03.pages.dev/course/notebook-blocks/aaa45a4607af423da4c9144dad703b56.html#b-683f23b8f9963856d210b2dd","content":"```\n# 当前项目中的独立材料：已存在则复用，缺失才从本讲原站准备。\nfrom pathlib import Path\nimport io, zipfile, requests\n_base = Path.cwd()\n_folder = 'lab10-clip'\n_sentinel = 'assets/chelsea-cat.png'\n_choices = [_base/_folder, _base/'lecture03-labs'/_folder, _base]\n_ready = next((p for p in _choices if (p/_sentinel).is_file()), None)\nif _ready is None:\n    _url = 'https://codingai-lec03.pages.dev/course/materials/' + _folder + '.zip'\n    _response = requests.get(_url, timeout=60)\n    _response.raise_for_status()\n    _payload = _response.content\n    with zipfile.ZipFile(io.BytesIO(_payload)) as _archive:\n        _names = [i.filename for i in _archive.infolist() if not i.is_dir()]\n        _prefix = _folder + '/'\n        _prefixed = all(n.startswith(_prefix) for n in _names)\n        _destination = _base if _prefixed else _base/_folder\n        for _item in _archive.infolist():\n            _target = (_destination/_item.filename).resolve()\n            if not _target.is_relative_to(_destination.resolve()):\n                raise ValueError('材料包中有越界路径，停止解压。')\n            if _item.is_dir():\n                _target.mkdir(parents=True, exist_ok=True)\n            elif not _target.exists():\n                _target.parent.mkdir(parents=True, exist_ok=True)\n                _target.write_bytes(_archive.read(_item))\n    _ready = next((p for p in _choices if (p/_sentinel).is_file()), None)\nassert _ready is not None, '请将本讲完整材料包解压到当前项目的 ' + _folder + '/；保留文件结构。'\nLAB_ROOT = _ready\nprint('材料目录已就绪：', LAB_ROOT)\n\nimport json, hashlib, platform, sys\nfrom pathlib import Path\nimport numpy as np\nimport matplotlib.pyplot as plt\nROOT=LAB_ROOT\nif not (ROOT/'assets').is_dir() and (ROOT/'lab10-clip'/'assets').is_dir():ROOT=ROOT/'lab10-clip'\nassert (ROOT/'assets').is_dir(), '请解压本实验完整包，并在该目录或其父目录运行。'\nOUT=ROOT/'runs/current'; OUT.mkdir(parents=True,exist_ok=True)\nFIG=OUT/'figures'; FIG.mkdir(exist_ok=True)\nplt.rcParams.update({'figure.dpi':120,'font.size':10,'axes.spines.top':False,'axes.spines.right':False})\nBLUE,GOLD,GREEN,PURPLE='#002676','#E6A500','#00856A','#69458D'\ndef sha_file(path):return hashlib.sha256(Path(path).read_bytes()).hexdigest()\ndef savefig(name):\n    if not plt.gcf().get_constrained_layout():plt.tight_layout()\n    plt.savefig(FIG/name,dpi=140,bbox_inches='tight');plt.show()\n\nimport torch\nfrom PIL import Image\n# 若宿主缺少固定预处理依赖，仅装入本次临时目录；不修改项目环境或下载模型权重。\nimport importlib.util, importlib.metadata, subprocess\ntry:\n    _transformers_version=importlib.metadata.version('transformers')\nexcept importlib.metadata.PackageNotFoundError:\n    _transformers_version=None\nif _transformers_version!='4.57.1':\n    _deps=ROOT/'_temporary_preprocessing_dependencies'\n    subprocess.check_call([sys.executable,'-m','pip','install','--quiet','--disable-pip-version-check',\n                           '--no-cache-dir','--target',str(_deps),'transformers==4.57.1',\n                           'numpy=='+np.__version__,'filelock>=3.20.3,<4'])\n    sys.path.insert(0,str(_deps))\n    importlib.invalidate_caches()\nfrom transformers import CLIPProcessor,CLIPImageProcessor,AutoTokenizer\nimport transformers\nassert transformers.__version__=='4.57.1', '请使用包内固定 requirements.txt。'\ntorch.set_num_threads(2)\nprovenance=json.loads((ROOT/'assets/provenance.json').read_text())\nassert sha_file(ROOT/'assets/chelsea-cat.png')==provenance['image_sha256']\nREVISION=provenance['revision']\nlocal=ROOT/'.model-cache'/REVISION\nconfig_local=ROOT/'model-config'\n# small verified config files ship in the package; weights are downloaded only on request.\nmanifest=json.loads((config_local/'manifest.json').read_text())\nfor f,expected in manifest['sha256'].items():assert sha_file(config_local/f)==expected\nclip_processor=CLIPProcessor(image_processor=CLIPImageProcessor.from_pretrained(config_local,local_files_only=True),tokenizer=AutoTokenizer.from_pretrained(config_local,local_files_only=True,use_fast=True))\nphoto=Image.open(ROOT/'assets/chelsea-cat.png').convert('RGB')\narms={'A_base':(['cat','dog','horse'],'a photo of a {}.'),'B_expand_only':(['cat','dog','horse','tiger','fox'],'a photo of a {}.'),'C_prompt_only':(['cat','dog','horse'],'a cropped photo of a {}.'),'D_remove_cat':(['dog','horse','tiger','fox'],'a photo of a {}.')}\nimage_inputs=clip_processor(images=photo,return_tensors='pt')\nall_prompts=list(dict.fromkeys(template.format(name) for names,template in arms.values() for name in names))\ntext_inputs=clip_processor(text=all_prompts,padding=True,return_tensors='pt')\nassert tuple(image_inputs['pixel_values'].shape)==(1,3,224,224)\nassert clip_processor.image_processor.__class__.__name__=='CLIPImageProcessor'\nassert clip_processor.tokenizer.__class__.__name__=='CLIPTokenizerFast'\npreprocess_verification={'scope':'preprocessing only, no weights loaded','pixel_shape':list(image_inputs['pixel_values'].shape),'pixel_sha256':hashlib.sha256(image_inputs['pixel_values'].numpy().tobytes()).hexdigest(),'prompt_count':len(all_prompts),'tokenizer':clip_processor.tokenizer.__class__.__name__,'image_processor':clip_processor.image_processor.__class__.__name__,'transformers':transformers.__version__,'image_sha256':sha_file(ROOT/'assets/chelsea-cat.png'),'revision':REVISION}\nhistorical_preprocess=json.loads((ROOT/'historical-v16/results/preprocessing-audit-20260918.json').read_text())\nassert preprocess_verification['pixel_sha256']==historical_preprocess['pixel_values_sha256']\nlegacy_processor=CLIPProcessor.from_pretrained(config_local,local_files_only=True)\nlegacy_image=legacy_processor(images=photo,return_tensors='pt')\nlegacy_text=legacy_processor(text=all_prompts,padding=True,return_tensors='pt')\nassert torch.equal(legacy_image['pixel_values'],image_inputs['pixel_values'])\nassert all(torch.equal(legacy_text[k],text_inputs[k]) for k in text_inputs)\npreprocess_verification['legacy_default_pixel_max_abs_difference']=float((legacy_image['pixel_values']-image_inputs['pixel_values']).abs().max())\npreprocess_verification['all_prompt_token_tensors_equal']=True\npreprocess_verification['token_ids_sha256']=hashlib.sha256(text_inputs['input_ids'].numpy().tobytes()).hexdigest()\n(OUT/'preprocessing-verification.json').write_text(json.dumps(preprocess_verification,indent=2));print(json.dumps(preprocess_verification,indent=2))\n\n```","sha256":"b49cd167f2cd93fe7431aea28959a8acf1559bfe30fb63d65ca0078b3ba9b785","chapter":{"id":"course","title":"2 · 独立准备并核对预处理 · 实现代码"},"unit":{"id":"notebook-blocks/aaa45a4607af423da4c9144dad703b56","title":"2 · 独立准备并核对预处理 · 实现代码"},"page":{"id":"reading-opening","title":"2 · 独立准备并核对预处理 · 实现代码","number":1},"sectionTitle":"2 · 独立准备并核对预处理 · 实现代码","currentQuestion":"2 · 独立准备并核对预处理 · 实现代码","sourceSlides":[],"knowledgeBlock":null,"formulas":[],"previousBlock":"b-0cc71f98f2ef9d93bcfd7f9d","nextBlock":null,"prerequisites":[{"id":"b-ebccbdbf54a9b6c5bf33b89b","url":"#b-ebccbdbf54a9b6c5bf33b89b","role":"section-title"},{"id":"b-4c9905e74e5444df2a75ff0f","url":"#b-4c9905e74e5444df2a75ff0f","role":"problem-context"}],"relatedBlocks":[]}]}
