Skip to content

feat(dvc): gzip + multi-chunk dvc_files tag serialization - #29

Merged
teri0411 merged 1 commit into
mainfrom
28-dvc-gz-upstream
Jul 22, 2026
Merged

feat(dvc): gzip + multi-chunk dvc_files tag serialization#29
teri0411 merged 1 commit into
mainfrom
28-dvc-gz-upstream

Conversation

@teri0411

Copy link
Copy Markdown
Contributor

Summary

Move the gzip + multi-chunk dvc_files tag serialization into upstream so publish (notebook) and serving share one implementation, fixing a serialize/deserialize split-brain (downstream nubison/mlplatform#691).

Previously the gz compression lived only in a downstream notebook-image patch. Serving runtime-installs the nubison version pinned in the model's requirements.txt (official 0.0.10), whose deserialize_dvc_info is plain json.loads — it raises on a gz: tag, so dvc_info={}, DVC restore is skipped, and the model fails to load (No such file: weights_custom.pkl).

Changes

  • Storage.py: serialize_dvc_info (gzip+base64, gz: prefix) / deserialize_dvc_info (gz: detection + plaintext backward compat) + new _chunk_tag_value / _reassemble_dvc_tag (split/rejoin dvc_files__N chunks so the tag stays under MAX_TAG_VAL_LENGTH=8000 for any file count).
  • Model.py: register writes tags.update(_chunk_tag_value(serialize_dvc_info(dvc_info))).
  • Service.py: reassembles chunks before deserializing on load.
  • test/test_storage.py: gz prefix / plaintext backward compat / chunk split+reassemble / 500-file over-limit full pipeline.

Backward compatibility

deserialize_dvc_info transparently handles both gz: and legacy plaintext JSON tags; single-chunk (no dvc_files__N) still works via _reassemble_dvc_tag.

Verification

  • Unit: test/test_storage.py new cases 7 PASS; test_storage.py+test_service.py regression 73 PASS.
  • Real serving (h100, PyPI-bypassed via wheel over HTTP): notebook publish wrote dvc_files=gz:...; the staging inference server installed this branch, ran DVC restore (6/6, no No such file), Service initialized, 1/1 Running, readyz/healthz/livez 200.

Closes #28

Compress the dvc_files MLflow tag (gzip+base64, 'gz:' prefix) and split
overflow into dvc_files__N chunks so the tag stays under the MLflow tag
limit (MAX_TAG_VAL_LENGTH=8000) regardless of file count. deserialize
detects the prefix and falls back to plaintext JSON for backward compat;
serving reassembles the chunks before deserializing.

Refs #28
@claude

claude Bot commented Jul 22, 2026

Copy link
Copy Markdown

리뷰

이슈 #28과 PR 설명을 확인했습니다. serialize_dvc_info/deserialize_dvc_info의 gz 프리픽스 처리, _chunk_tag_value/_reassemble_dvc_tag의 분할·재조합 로직, Model.py(registerService.py(_get_dvc_info_from_model_uri) 호출부를 코드 레벨에서 검증했고, publish(tags.updatemlflow.set_tags + set_model_version_tag 루프)와 serving(_reassemble_dvc_tagdeserialize_dvc_info) 양쪽 경로가 서로 대응되게 잘 연결되어 있습니다. 레거시 평문 JSON 태그에 대한 하위호환도 startswith("gz:") 분기로 올바르게 처리됩니다. 실제 서빙 환경(h100)에서 검증까지 마친 것도 확인했습니다. 다음은 사소한 개선 제안입니다 (머지를 막을 정도는 아닙니다).

  1. Service.py 통합 경로에 대한 회귀 테스트 부재: test_storage.pyserialize/deserialize/chunk/reassemble 유닛 테스트는 충분히 추가되었지만, 정작 이번 이슈의 근본 원인이었던 "publish가 쓴 태그를 serving이 못 읽는" split-brain 케이스를 재현하는 test_service.py 통합 테스트는 없습니다. _get_dvc_info_from_model_uri{"dvc_files": "...", "dvc_files__1": "..."} 형태의 mock tags를 주입해 최종적으로 원본 dvc_info dict가 복원되는지 검증하는 테스트를 하나 추가하면, 향후 이 경로가 다시 깨졌을 때 CI에서 바로 잡아낼 수 있을 것 같습니다.

  2. serialize_dvc_info/deserialize_dvc_info 내부의 반복 import: 함수 호출마다 import base64, import gzip을 수행하고 있는데(Storage.py:411-412, 421-422), 두 모듈 다 표준 라이브러리이고 순환 임포트 우려도 없으므로 파일 상단으로 옮기는 것이 일반적인 스타일에 맞고 약간의 반복 오버헤드도 줄일 수 있습니다.

  3. _reassemble_dvc_tag의 falsy 체크 (Storage.py:391): if not base: return Nonebase가 빈 문자열("")인 경우도 None으로 취급합니다. 실제로 serialize_dvc_info는 항상 "gz:" 프리픽스가 붙은 비어있지 않은 문자열을 생성하므로 현재 실질적인 영향은 없지만, 의도를 더 명확히 하려면 if base is None:으로 바꾸는 것도 고려해볼 만합니다.

전반적으로 이슈에서 요구한 스코프(gz 압축 + 멀티청크 + 하위호환)를 정확히 구현했고, 테스트도 (통합 테스트 하나를 제외하면) 꼼꼼합니다. 승인해도 좋을 것 같습니다.

@teri0411
teri0411 merged commit 122dd47 into main Jul 22, 2026
4 checks passed
@teri0411
teri0411 deleted the 28-dvc-gz-upstream branch July 22, 2026 10:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Upstream gzip + multi-chunk DVC tag serialization for serving compatibility

1 participant