Download src/captioning/baselines/cnn.py from apoorvrajdev/image-captioning-api: direct link, hf CLI and curl.
- Browser
- Download file 3.53 kB
-
https://huggingface.co/spaces/apoorvrajdev/image-captioning-api/resolve/main/src/captioning/baselines/cnn.py
- Command line
-
hf download hf://spaces/apoorvrajdev/image-captioning-api/src/captioning/baselines/cnn.py
-
curl -L -o cnn.py https://huggingface.co/spaces/apoorvrajdev/image-captioning-api/resolve/main/src/captioning/baselines/cnn.py
3.53 kB
| """The project's CNN + Transformer as a :class:`Captioner`.""" | |
| from __future__ import annotations | |
| from pathlib import Path | |
| from typing import TYPE_CHECKING, Any, Protocol | |
| from captioning.baselines.base import Captioner, CaptionerIdentity | |
| from captioning.config.schema import AppConfig, ComparedModelConfig | |
| if TYPE_CHECKING: | |
| from captioning.inference.predictor import DecodeStrategy | |
| class _ModelSettings(Protocol): | |
| max_length: int | |
| class _PredictorConfig(Protocol): | |
| def model(self) -> _ModelSettings: ... | |
| class PathPredictor(Protocol): | |
| """The part of ``CaptionPredictor`` the adapter relies on.""" | |
| decode_strategy: str | |
| beam_width: int | |
| length_penalty: float | |
| repetition_penalty: float | |
| no_repeat_ngram_size: int | |
| def config(self) -> _PredictorConfig: ... | |
| def predict_path(self, image_path: str | Path) -> str: ... | |
| class CNNCaptioner(Captioner): | |
| """Wraps a loaded ``CaptionPredictor`` without changing how it decodes. | |
| Each image goes through ``predictor.predict_path``, one at a time, exactly | |
| as ``scripts/evaluate.py`` does. The recorded decode settings follow | |
| ``run_meta.json``: beam-only parameters are ``None`` for greedy decoding. | |
| """ | |
| def __init__(self, predictor: PathPredictor, model: ComparedModelConfig) -> None: | |
| beam = predictor.decode_strategy == "beam" | |
| super().__init__( | |
| CaptionerIdentity( | |
| model_id=model.model_id, | |
| hub_repo=model.hub_repo, | |
| revision=model.revision, | |
| decode_settings={ | |
| "decode_strategy": predictor.decode_strategy, | |
| "beam_width": predictor.beam_width if beam else None, | |
| "length_penalty": predictor.length_penalty if beam else None, | |
| "repetition_penalty": predictor.repetition_penalty, | |
| "no_repeat_ngram_size": predictor.no_repeat_ngram_size, | |
| "max_length": predictor.config.model.max_length, | |
| }, | |
| ) | |
| ) | |
| self._predictor = predictor | |
| def from_artifacts( | |
| cls, | |
| weights_path: str | Path, | |
| tokenizer_dir: str | Path, | |
| config: AppConfig, | |
| *, | |
| decode_strategy: DecodeStrategy | None = None, | |
| beam_width: int | None = None, | |
| length_penalty: float | None = None, | |
| repetition_penalty: float | None = None, | |
| no_repeat_ngram_size: int | None = None, | |
| ) -> CNNCaptioner: | |
| """Load the checkpoint with ``CaptionPredictor.from_artifacts``. | |
| Decoding arguments are passed through unchanged, so unset ones fall | |
| back to ``config.serve`` just as they do for ``scripts/evaluate.py``. | |
| The identity comes from ``config.compare.cnn``. TensorFlow is imported | |
| here, not when this module is imported. | |
| """ | |
| from captioning.inference.predictor import CaptionPredictor | |
| predictor: Any = CaptionPredictor.from_artifacts( | |
| weights_path, | |
| tokenizer_dir, | |
| config, | |
| decode_strategy=decode_strategy, | |
| beam_width=beam_width, | |
| length_penalty=length_penalty, | |
| repetition_penalty=repetition_penalty, | |
| no_repeat_ngram_size=no_repeat_ngram_size, | |
| ) | |
| return cls(predictor, config.compare.cnn) | |
| def _raw_captions(self, image_paths: list[Path]) -> list[str]: | |
| return [self._predictor.predict_path(path) for path in image_paths] | |