Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 18 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ There are two main ways to execute configure the conversion process:

1. **NN Archive**:
Alternatively, you can use an [NN Archive](https://docs.luxonis.com/software-v3/ai-inference/nn-archive/#NN%20Archive) as input. An NN Archive includes a model in one of the supported formats—ONNX (.onnx), OpenVINO IR (.xml and .bin), or TensorFlow Lite (.tflite)—alongside a `config.json` file. The config.json file follows a specific configuration format as described under the `Configuration` section.
1. **YAML Configuration File (Legacy)**:
2. **YAML Configuration File (Legacy)**:
An alternative way to configure the conversion is through a YAML configuration file. For reference, you can check [defaults.yaml](shared_with_container/configs/defaults.yaml) and other examples located in the [shared_with_container/configs](shared_with_container/configs) directory.

**Modifying Settings with Command-Line Arguments**:
Expand Down Expand Up @@ -324,6 +324,9 @@ shared_with_container/
│ ├── resnet18.yaml
│ └── <configs will be downloaded here>
├── misc/
│ └── <internal scratch files>
├── models/
│ ├── resnet18.onnx
│ └── <models will be downloaded here>
Expand All @@ -345,7 +348,9 @@ The converter first searches for files exactly at the provided path. If not foun
The `output_dir` can be specified using the `--output-dir` CLI argument. If such a directory already exists, the `output_dir_name` will be appended with the current date and time. If not specified, the `output_dir_name` will be autogenerated in the following format: `<model_name>_to_<target>_<date>_<time>`.

> [!NOTE]
> When running the CLI, `shared_with_container` must be present in the current working directory, and all paths provided to the CLI must be specified relative to the `shared_with_container` directory.
> When running the `modelconverter` CLI, `shared_with_container` and its standard subdirectories are created automatically in the current working directory if they do not exist yet.
> With the default CLI, local input files should be placed under `shared_with_container/`, for example `configs/resnet18.yaml` or `models/resnet18.onnx`.
> Files outside of `shared_with_container/` are not visible to the container unless you mount them separately. Remote paths such as `s3://...` and `gs://...` work as usual.

### Running ModelConverter

Expand All @@ -359,11 +364,17 @@ You can run the built image either manually using the `docker run` command or us
export AWS_S3_ENDPOINT_URL=<your_aws_s3_endpoint_url>
```

1. If `shared_with_container` directory doesn't exist on your host, create it.
2. If using the `modelconverter` CLI, `shared_with_container` is created automatically in the current working directory if it does not exist yet.

- If using `docker run` manually, create `shared_with_container` on the host first so it can be mounted into the container:

```bash
mkdir -p shared_with_container
```

1. Without remote files, place the model, config, and calibration data in the respective directories (refer [Sharing Files](#sharing-files)).
3. Without remote files, place the model, config, and calibration data somewhere under `shared_with_container/` (refer [Sharing Files](#sharing-files)).

1. Execute the conversion:
4. Execute the conversion:

- If using the `modelconverter` CLI:

Expand Down Expand Up @@ -641,8 +652,8 @@ optionally saves the results to a `.csv` file.
ModelConverter offers additional analysis tools for the RVC4 platform. The tools provide an in-depth look at the following:

1. The outputs of all layers in comparison to the ground truth ONNX model,
1. The cycle usage of each layer on an RVC4 device.
1. Visualizations for fast and easy comparison of multiple models.
2. The cycle usage of each layer on an RVC4 device.
3. Visualizations for fast and easy comparison of multiple models.

This gives the user better insight into the successful quantization of a model, helps discover potential speed bottleneck layers, and allows for the comparison of different quantization parameters.

Expand Down
1 change: 1 addition & 0 deletions modelconverter/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,7 @@ def launcher(
if in_docker():
return command(*bound.args, **bound.kwargs)

init_dirs()
tag = "dev" if dev else "latest"

target = bound.arguments["target"]
Expand Down
16 changes: 15 additions & 1 deletion modelconverter/cli/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
MISC_DIR,
MODELS_DIR,
OUTPUTS_DIR,
RUNTIME_CACHE_SUFFIX,
RUNTIME_HOME_SUFFIX,
SHARED_DIR,
)
from modelconverter.utils.hub_requests import Request
from modelconverter.utils.types import DataType, Encoding, Target
Expand Down Expand Up @@ -66,7 +69,18 @@ def get_output_dir_name(


def init_dirs() -> None:
for p in [CONFIGS_DIR, MODELS_DIR, OUTPUTS_DIR, CALIBRATION_DIR]:
for p in [
SHARED_DIR,
MISC_DIR,
# Some tools run inside the container as the host UID and still
# expect writable HOME/XDG cache locations.
MISC_DIR / RUNTIME_HOME_SUFFIX,
MISC_DIR / RUNTIME_CACHE_SUFFIX,
CONFIGS_DIR,
MODELS_DIR,
OUTPUTS_DIR,
CALIBRATION_DIR,
]:
logger.debug(f"Creating {p}")
p.mkdir(parents=True, exist_ok=True)

Expand Down
4 changes: 4 additions & 0 deletions modelconverter/utils/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,16 @@
OUTPUTS_DIR: Final[Path] = SHARED_DIR / "outputs"
CALIBRATION_DIR: Final[Path] = SHARED_DIR / "calibration_data"
MODELS_DIR: Final[Path] = SHARED_DIR / "models"
RUNTIME_HOME_SUFFIX: Final[str] = "runtime-home"
RUNTIME_CACHE_SUFFIX: Final[str] = "runtime-cache"
LOADERS = Registry(name="loaders")

__all__ = [
"CALIBRATION_DIR",
"CONFIGS_DIR",
"MODELS_DIR",
"OUTPUTS_DIR",
"RUNTIME_CACHE_SUFFIX",
"RUNTIME_HOME_SUFFIX",
"SHARED_DIR",
]
25 changes: 25 additions & 0 deletions modelconverter/utils/docker_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@

import docker
from modelconverter import __version__
from modelconverter.utils.constants import (
RUNTIME_CACHE_SUFFIX,
RUNTIME_HOME_SUFFIX,
)

_CONTAINER_MISC_DIR = "/app/shared_with_container/misc"
_CONTAINER_USER_HOME = f"{_CONTAINER_MISC_DIR}/{RUNTIME_HOME_SUFFIX}"
_CONTAINER_USER_CACHE = f"{_CONTAINER_MISC_DIR}/{RUNTIME_CACHE_SUFFIX}"


def get_docker_client_from_active_context() -> docker.DockerClient:
Expand Down Expand Up @@ -73,6 +81,7 @@
memory: str | None = None,
cpus: float | None = None,
) -> str:
user_spec = _get_current_user_spec()
config = {
"services": {
"modelconverter": {
Expand Down Expand Up @@ -104,6 +113,14 @@
}
},
}
if user_spec is not None:
config["services"]["modelconverter"]["user"] = user_spec
config["services"]["modelconverter"]["environment"].update(
{
"HOME": _CONTAINER_USER_HOME,
"XDG_CACHE_HOME": _CONTAINER_USER_CACHE,
}
)
limits = {}
if memory is not None:
limits["memory"] = memory
Expand All @@ -121,6 +138,14 @@
return yaml.dump(config)


def _get_current_user_spec() -> str | None:
getuid = getattr(os, "getuid", None)
getgid = getattr(os, "getgid", None)
if not callable(getuid) or not callable(getgid):
return None
return f"{getuid()}:{getgid()}"


def in_docker() -> bool:
return "IN_DOCKER" in os.environ

Expand Down Expand Up @@ -261,7 +286,7 @@
tmp_path: Path | None = None
try:
request = Request(url, headers={"User-Agent": "modelconverter"}) # noqa: S310
with urlopen(request, timeout=30) as response: # noqa: S310

Check failure on line 289 in modelconverter/utils/docker_utils.py

View workflow job for this annotation

GitHub Actions / semgrep/ci

Semgrep Issue

Detected a dynamic value being used with urllib. urllib supports 'file://' schemes, so a dynamic value controlled by a malicious actor may allow them to read arbitrary files. Audit uses of urllib calls to ensure user data cannot control the URLs, or consider using the 'requests' library instead.
if getattr(response, "status", 200) >= 400:
raise RuntimeError(
f"HTTP {response.status} while downloading {url}"
Expand Down
Loading