Skip to content

Commit b614d8e

Browse files
author
hualxie
committed
improve copy from #382
1 parent 41b1b50 commit b614d8e

32 files changed

Lines changed: 117 additions & 52 deletions

File tree

.aitk/configs/checks.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"configCheck": 167,
3-
"copyCheck": 182,
3+
"copyCheck": 184,
44
"extensionCheck": 2,
55
"gitignoreCheck": 44,
66
"inferenceModelCheck": 25,
@@ -12,5 +12,6 @@
1212
"pathCheck": 1423,
1313
"requirementsCheck": 37,
1414
"templateCheck": 3,
15-
"venvRequirementsCheck": 17
15+
"venvRequirementsCheck": 17,
16+
"winmlCopyCheck": 39
1617
}

.aitk/scripts/project_processor.py

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,24 @@
44
from pathlib import Path
55
from typing import Dict, List, Optional
66

7-
import yaml
87
from model_lab import RuntimeEnum
98
from sanitize.constants import ArchitectureEnum, EPNames, IconEnum, ModelStatusEnum
10-
from sanitize.copy_config import CopyConfig
9+
from sanitize.copy_config import Copy, CopyConfig
1110
from sanitize.generator_amd import generator_amd
1211
from sanitize.generator_dml import generator_dml
1312
from sanitize.generator_intel import generator_intel
1413
from sanitize.generator_qnn import generator_qnn
1514
from sanitize.generator_trtrtx import generator_trtrtx
1615
from sanitize.model_info import ModelInfo, ModelList
1716
from sanitize.project_config import ModelInfoProject, ModelProjectConfig, WorkflowItem
18-
from sanitize.utils import GlobalVars, isLLM_by_id, open_ex
17+
from sanitize.utils import (
18+
GlobalVars,
19+
WINML_COPY_EXEMPT_IDS,
20+
isLLM_by_id,
21+
iter_aitk_info_yml,
22+
open_ex,
23+
winml_copy_src_for,
24+
)
1925

2026
def fetch_pipeline_tags(model_link: str) -> Optional[List[str]]:
2127
"""Fetch pipeline_tag from HuggingFace API for a given model link.
@@ -209,22 +215,9 @@ def project_processor():
209215

210216
all_ids = set()
211217
all_summary = AllModelSummary()
212-
for yml_file in root_dir.rglob("info.yml"):
218+
for yml_file, yaml_object in iter_aitk_info_yml(root_dir):
213219
# if "DEBUG_ID" in str(yml_file):
214220
# pass
215-
# read yml file as yaml object
216-
with yml_file.open("r", encoding="utf-8") as file:
217-
try:
218-
yaml_content = file.read()
219-
yaml_object = yaml.safe_load(yaml_content)
220-
except yaml.YAMLError as e:
221-
print(f"Error reading {yml_file}: {e}")
222-
continue
223-
aitk = yaml_object.get("aitk", [])
224-
if not aitk:
225-
if yml_file.parent.name == "aitk":
226-
raise KeyError(f"aitk not found in {yml_file}")
227-
continue
228221
print(f"Process aitk for {yml_file}")
229222
# model info
230223
modelInfo = convert_yaml_to_model_info(root_dir, yml_file, yaml_object)
@@ -236,10 +229,24 @@ def project_processor():
236229
raise KeyError(f"same id found in {yml_file}")
237230
all_ids.add(modelInfo.id.lower())
238231
modelList.models.append(modelInfo)
239-
# copy pre
232+
# copy pre — auto-ensure winml.py copy entry (unless exempt), then run pre-phase copies
240233
copyConfigFile = yml_file.parent / "_copy.json.config"
241-
if copyConfigFile.exists():
242-
copyConfig = CopyConfig.Read(copyConfigFile.as_posix())
234+
copyConfig: CopyConfig | None = (
235+
CopyConfig.Read(copyConfigFile.as_posix()) if copyConfigFile.exists() else None
236+
)
237+
if modelInfo.id not in WINML_COPY_EXEMPT_IDS:
238+
desired_src = winml_copy_src_for(modelInfo.id)
239+
if copyConfig is None:
240+
copyConfig = CopyConfig()
241+
copyConfig._file = str(copyConfigFile)
242+
copyConfig._fileContent = None
243+
existing = next((c for c in copyConfig.copies if c.dst == "winml.py"), None)
244+
if existing is None:
245+
copyConfig.copies.append(Copy(src=desired_src, dst="winml.py"))
246+
elif existing.src != desired_src:
247+
existing.src = desired_src
248+
GlobalVars.winmlCopyCheck += 1
249+
if copyConfig is not None:
243250
copyConfig.process(yml_file.parent.as_posix(), pre=True)
244251
copyConfig.writeIfChanged()
245252
# model summary
@@ -258,4 +265,4 @@ def project_processor():
258265

259266

260267
if __name__ == "__main__":
261-
project_processor()
268+
project_processor()

.aitk/scripts/sanitize/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ def main():
6363
version = model.version
6464
modelVerDir = modelDir if model.relativePath else os.path.join(modelDir, str(version))
6565

66-
# process copy
66+
# process copy (post phase — .json.config copies; winml.py is auto-ensured earlier in project_processor)
6767
copyConfigFile = os.path.join(modelVerDir, "_copy.json.config")
6868
if os.path.exists(copyConfigFile):
6969
copyConfig = CopyConfig.Read(copyConfigFile)

.aitk/scripts/sanitize/utils.py

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,41 @@
66
import json
77
import os
88
from contextlib import contextmanager
9-
from typing import Any
9+
from pathlib import Path
10+
from typing import Any, Iterator, Tuple
1011

1112
import pydash
13+
import yaml
1214
from model_lab import RuntimeEnum
1315

1416
from .constants import EPNames, OliveDeviceTypes, OlivePropertyNames
1517

1618

19+
def iter_aitk_info_yml(root_dir: Path) -> Iterator[Tuple[Path, dict]]:
20+
"""Yield (yml_file, yaml_object) for each info.yml under root_dir that has
21+
a top-level `aitk` key.
22+
23+
Files that fail to parse are skipped with a printed warning. An info.yml
24+
sitting under a folder literally named `aitk` but missing the `aitk` key
25+
raises KeyError, matching the invariant enforced by project_processor.
26+
"""
27+
for yml_file in root_dir.rglob("info.yml"):
28+
try:
29+
with yml_file.open("r", encoding="utf-8") as f:
30+
yaml_object = yaml.safe_load(f.read())
31+
except yaml.YAMLError as e:
32+
print(f"Error reading {yml_file}: {e}")
33+
continue
34+
if not isinstance(yaml_object, dict):
35+
continue
36+
aitk = yaml_object.get("aitk")
37+
if not aitk:
38+
if yml_file.parent.name == "aitk":
39+
raise KeyError(f"aitk not found in {yml_file}")
40+
continue
41+
yield yml_file, yaml_object
42+
43+
1744
class GlobalVars:
1845
errorList = []
1946
verbose = False
@@ -34,6 +61,7 @@ class GlobalVars:
3461
copyCheck = 0
3562
licenseCheck = 0
3663
venvRequirementsCheck = set()
64+
winmlCopyCheck = 0
3765

3866
oliveCheck = 0
3967
RuntimeToEPName = {
@@ -209,6 +237,23 @@ def isLLM_by_id(id: str) -> bool:
209237
return any(check in id for check in check_list)
210238

211239

240+
# Projects that are themselves canonical winml.py sources and should not have
241+
# a winml.py copy entry auto-added to their _copy.json.config.
242+
WINML_COPY_EXEMPT_IDS = {
243+
"huggingface/Intel/bert-base-uncased-mrpc",
244+
"huggingface/deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B",
245+
}
246+
247+
# Canonical winml.py sources. Paths are relative to the project's aitk folder
248+
# (matches the CopyConfig `src` format).
249+
WINML_SRC_LLM = "../../deepseek-ai-DeepSeek-R1-Distill-Qwen-1.5B/aitk/winml.py"
250+
WINML_SRC_NON_LLM = "../../intel-bert-base-uncased-mrpc/aitk/winml.py"
251+
252+
253+
def winml_copy_src_for(model_id: str) -> str:
254+
return WINML_SRC_LLM if isLLM_by_id(model_id) else WINML_SRC_NON_LLM
255+
256+
212257
# TODO align with Skylight\vscode\ai-mlstudio\src\model-lab\utilities\runtimeUtils.ts
213258
def get_execute_runtime(runtime: RuntimeEnum) -> RuntimeEnum:
214259
if runtime in [RuntimeEnum.IntelAny, RuntimeEnum.IntelCPU, RuntimeEnum.IntelGPU, RuntimeEnum.IntelNPU]:
@@ -231,4 +276,4 @@ def get_eval_runtime(runtime: RuntimeEnum, isLLM: bool) -> RuntimeEnum:
231276
def get_eval_in_execute_runtime(runtime: RuntimeEnum) -> RuntimeEnum:
232277
if runtime == RuntimeEnum.QNN or runtime == RuntimeEnum.QNNGPU:
233278
return RuntimeEnum.QNN
234-
raise ValueError(f"Unsupported runtime for eval in execute: {runtime}")
279+
raise ValueError(f"Unsupported runtime for eval in execute: {runtime}")
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"copies": [
3+
{
4+
"src": "../../intel-bert-base-uncased-mrpc/aitk/winml.py",
5+
"dst": "winml.py"
6+
}
7+
]
8+
}

Qwen-Qwen2.5-0.5B-Instruct/aitk/_copy.json.config

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
"dst": "requirements.txt"
3636
},
3737
{
38-
"src": "../../intel-bert-base-uncased-mrpc/aitk/winml.py",
38+
"src": "../../deepseek-ai-DeepSeek-R1-Distill-Qwen-1.5B/aitk/winml.py",
3939
"dst": "winml.py"
4040
}
4141
]

Qwen-Qwen2.5-0.5B/aitk/_copy.json.config

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"replacements": []
77
},
88
{
9-
"src": "../../intel-bert-base-uncased-mrpc/aitk/winml.py",
9+
"src": "../../deepseek-ai-DeepSeek-R1-Distill-Qwen-1.5B/aitk/winml.py",
1010
"dst": "winml.py"
1111
}
1212
]

Qwen-Qwen2.5-1.5B-Instruct/aitk/_copy.json.config

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
]
6363
},
6464
{
65-
"src": "../../intel-bert-base-uncased-mrpc/aitk/winml.py",
65+
"src": "../../deepseek-ai-DeepSeek-R1-Distill-Qwen-1.5B/aitk/winml.py",
6666
"dst": "winml.py"
6767
}
6868
]

Qwen-Qwen2.5-14B-Instruct/aitk/_copy.json.config

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
"dst": "requirements.txt"
4040
},
4141
{
42-
"src": "../../intel-bert-base-uncased-mrpc/aitk/winml.py",
42+
"src": "../../deepseek-ai-DeepSeek-R1-Distill-Qwen-1.5B/aitk/winml.py",
4343
"dst": "winml.py"
4444
},
4545
{

Qwen-Qwen2.5-3B-Instruct/aitk/_copy.json.config

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
"dst": "requirements.txt"
2626
},
2727
{
28-
"src": "../../intel-bert-base-uncased-mrpc/aitk/winml.py",
28+
"src": "../../deepseek-ai-DeepSeek-R1-Distill-Qwen-1.5B/aitk/winml.py",
2929
"dst": "winml.py"
3030
},
3131
{

0 commit comments

Comments
 (0)