git: 8f2823654667 - main - science/linux-ai-ml-env: Linux Python environment for running AI and ML stuff

From: Gleb Popov <arrowd_at_FreeBSD.org>
Date: Fri, 28 Mar 2025 12:37:30 UTC
The branch main has been updated by arrowd:

URL: https://cgit.FreeBSD.org/ports/commit/?id=8f2823654667cc746695a83126e15c3172c6261d

commit 8f2823654667cc746695a83126e15c3172c6261d
Author:     Alexey Donskov <voxnod@gmail.com>
AuthorDate: 2025-03-22 16:59:25 +0000
Commit:     Gleb Popov <arrowd@FreeBSD.org>
CommitDate: 2025-03-28 12:37:25 +0000

    science/linux-ai-ml-env: Linux Python environment for running AI and ML stuff
    
    Sponsored by:   Future Crew, LLC
    Pull Request:   https://github.com/freebsd/freebsd-ports/pull/361
---
 science/Makefile                                   |  1 +
 science/linux-ai-ml-env/Makefile                   | 99 ++++++++++++++++++++++
 science/linux-ai-ml-env/distinfo                   |  5 ++
 science/linux-ai-ml-env/files/ai-ml-env-bash.in    |  6 ++
 science/linux-ai-ml-env/files/ai-ml-env-python.in  |  4 +
 .../patch-reinforcement__learning_actor__critic.py | 13 +++
 .../patch-reinforcement__learning_reinforce.py     | 12 +++
 .../patch-time__sequence__prediction_train.py      | 11 +++
 .../files/patch-word__language__model_main.py      | 11 +++
 science/linux-ai-ml-env/files/redundant-items.txt  | 41 +++++++++
 science/linux-ai-ml-env/files/requirements.txt     | 56 ++++++++++++
 .../files/stable-diffusion-sample.py               | 24 ++++++
 science/linux-ai-ml-env/files/uvm_ioctl_override.c | 93 ++++++++++++++++++++
 science/linux-ai-ml-env/pkg-descr                  |  5 ++
 science/linux-ai-ml-env/pkg-message                | 32 +++++++
 science/linux-ai-ml-env/pkg-plist                  | 26 ++++++
 16 files changed, 439 insertions(+)

diff --git a/science/Makefile b/science/Makefile
index ae3b09cb79e2..c35f2114c848 100644
--- a/science/Makefile
+++ b/science/Makefile
@@ -168,6 +168,7 @@
     SUBDIR += libxc
     SUBDIR += liggghts
     SUBDIR += linearelasticity
+    SUBDIR += linux-ai-ml-env
     SUBDIR += linux-zotero
     SUBDIR += luscus
     SUBDIR += m-aneos
diff --git a/science/linux-ai-ml-env/Makefile b/science/linux-ai-ml-env/Makefile
new file mode 100644
index 000000000000..4053a20d88c0
--- /dev/null
+++ b/science/linux-ai-ml-env/Makefile
@@ -0,0 +1,99 @@
+PORTNAME=	ai-ml-env
+PORTVERSION=	1.0.0
+CATEGORIES=	science linux
+MASTER_SITES=	https://arrowd.name/
+PKGNAMEPREFIX=	linux-
+DISTFILES=	miniconda3.tar.gz
+DIST_SUBDIR=	${PORTNAME}
+
+MAINTAINER=	voxnod@gmail.com
+COMMENT=	Linux Python environment for running Stable Diffusion models and PyTorch CUDA examples
+
+ONLY_FOR_ARCHS=	amd64
+
+LICENSE=	MULTI
+LICENSE_NAME=	Multiple licenses
+LICENSE_TEXT=	The package contains multiple packages with different licenses
+LICENSE_PERMS=	dist-mirror pkg-mirror auto-accept
+
+FETCH_DEPENDS=	linux_base-rl9>=9.2:emulators/linux_base-rl9
+BUILD_DEPENDS=	linux-rl9-devtools>=0:devel/linux-rl9-devtools
+RUN_DEPENDS=	linux-nvidia-libs>=0:x11/linux-nvidia-libs \
+		linux-rl9-python${PYTHON_SUFFIX}>=0:lang/linux-rl9-python3 \
+		nvidia-driver>=0:x11/nvidia-driver
+
+USES=		linux:rl9
+USE_LINUX_PREFIX=	yes
+USE_GITHUB=	nodefault
+GH_ACCOUNT=	pytorch:examples
+GH_PROJECT=	examples:examples
+GH_TAGNAME=	5dfeb46902baf444010f2f54bcf4dfbea109ae4d:examples
+
+WRKSRC=		${WRKSRC_examples}
+
+SUB_FILES=	ai-ml-env-bash \
+		ai-ml-env-python
+SUB_LIST=	LOCALBASE=${LOCALBASE} \
+		LINUXBASE=${LINUXBASE}
+
+PLIST_SUB+=     PYTHON_SUFFIX=${PYTHON_SUFFIX} \
+		PYTHON_VER=${PYTHON_VER}
+
+CONDA_VERSION=	py39_25.1.1-2
+CONDA_SCRIPT=	Miniconda3-${CONDA_VERSION}-Linux-x86_64.sh
+PYTHON_SUFFIX=	39
+PYTHON_VER=	3.9
+DATA_DIR=	${LOCALBASE}/share/${PORTNAME}
+
+create-distfile:
+	${MKDIR} ${DISTDIR}/${DIST_SUBDIR}
+	cd ${DISTDIR}/${DIST_SUBDIR} && \
+		fetch -a -v https://repo.anaconda.com/miniconda/${CONDA_SCRIPT}
+	@if [ ! -d "${DISTDIR}/${DIST_SUBDIR}/miniconda3/envs/pytorch" ]; then \
+		${ECHO_MSG} "Miniconda environment 'pytorch' not found. Setting up..."; \
+		${SETENV} HOME=${DISTDIR}/${DIST_SUBDIR} ${SH} ${DISTDIR}/${DIST_SUBDIR}/${CONDA_SCRIPT} -b -s; \
+		${DISTDIR}/${DIST_SUBDIR}/miniconda3/bin/conda create --name pytorch python=${PYTHON_VER} -y; \
+		${LINUXBASE}/bin/bash -c "source ${DISTDIR}/${DIST_SUBDIR}/miniconda3/etc/profile.d/conda.sh && \
+			conda activate pytorch && \
+			pip install -r ${FILESDIR}/requirements.txt"; \
+	fi
+	cd ${DISTDIR}/${DIST_SUBDIR} && \
+		tar -czf miniconda3.tar.gz miniconda3
+	${MAKE} makesum
+
+do-build:
+	/compat/linux/bin/cc --sysroot=/compat/linux -m64 -std=c99 -Wall -ldl -fPIC -shared -o ${WRKDIR}/dummy-uvm.so ${FILESDIR}/uvm_ioctl_override.c
+
+do-install:
+	@${FIND} ${WRKSRC} -name '*.orig' -delete
+	# Install Linux Python packages
+	${MKDIR} ${STAGEDIR}${PREFIX}/usr/bin
+	${FIND} ${WRKDIR}/miniconda3/envs/pytorch/bin -type f -exec ${CP} {} ${STAGEDIR}${PREFIX}/usr/bin \;
+	${MKDIR} ${STAGEDIR}${PREFIX}/usr/lib/python${PYTHON_VER}
+	${CP} -r ${WRKDIR}/miniconda3/envs/pytorch/lib/python${PYTHON_VER}/site-packages ${STAGEDIR}${PREFIX}/usr/lib/python${PYTHON_VER}
+	for item in `cat ${FILESDIR}/redundant-items.txt`; do \
+		${RM} -r ${STAGEDIR}${PREFIX}/usr/$$item; \
+	done
+	${FIND} ${STAGEDIR}${PREFIX}/usr/bin -type f -exec ${REINPLACE_CMD} -i '' 's|^#!.*/miniconda3/envs/pytorch/bin/python|#!/bin/python3|' {} +
+	# Install Shkhln's lib
+	${MKDIR} ${STAGEDIR}${DATADIR}
+	${INSTALL_LIB} ${WRKDIR}/dummy-uvm.so ${STAGEDIR}${DATADIR}
+	# Install Pytorch examples
+	${MKDIR} ${STAGEDIR}${DATA_DIR}/pytorch-examples
+	cd ${WRKSRC} && \
+		${COPYTREE_SHARE} . ${STAGEDIR}${DATA_DIR}/pytorch-examples
+	${RM} -r ${STAGEDIR}${DATA_DIR}/pytorch-examples/.github
+	${INSTALL_SCRIPT} ${WRKSRC}/run_python_examples.sh ${STAGEDIR}${DATA_DIR}/pytorch-examples
+	# Install Stable Diffusion sample
+	${INSTALL_DATA} ${FILESDIR}/stable-diffusion-sample.py ${STAGEDIR}${DATA_DIR}
+	# Install demonstration scripts
+	${MKDIR} ${STAGEDIR}${LOCALBASE}/bin
+	${INSTALL_SCRIPT} ${WRKDIR}/ai-ml-env-bash ${STAGEDIR}${LOCALBASE}/bin/ai-ml-env-bash
+	${INSTALL_SCRIPT} ${WRKDIR}/ai-ml-env-python ${STAGEDIR}${LOCALBASE}/bin/ai-ml-env-python
+
+post-install:
+	@${FIND} ${STAGEDIR}${PREFIX}/usr/lib/python${PYTHON_VER} -type f | sed -e 's|${STAGEDIR}${PREFIX}/||' >> ${TMPPLIST}
+	@${FIND} ${STAGEDIR}${DATA_DIR}/pytorch-examples -type f | sed -e 's|${STAGEDIR}||' >> ${TMPPLIST}
+	@${FIND} ${STAGEDIR}${DATA_DIR} -type d | sed -e 's|${STAGEDIR}|@dir |' >> ${TMPPLIST}
+
+.include <bsd.port.mk>
diff --git a/science/linux-ai-ml-env/distinfo b/science/linux-ai-ml-env/distinfo
new file mode 100644
index 000000000000..eba6ad95a915
--- /dev/null
+++ b/science/linux-ai-ml-env/distinfo
@@ -0,0 +1,5 @@
+TIMESTAMP = 1742925172
+SHA256 (ai-ml-env/miniconda3.tar.gz) = 1d9eb42dd753f462f4ccd82ab7716561b90274eeaa45254fd50b879bb09537b7
+SIZE (ai-ml-env/miniconda3.tar.gz) = 3511877484
+SHA256 (ai-ml-env/pytorch-examples-5dfeb46902baf444010f2f54bcf4dfbea109ae4d_GH0.tar.gz) = a024b134dfd1edba649289e551a0cd85bd22424dd76df4303b280e20757a602c
+SIZE (ai-ml-env/pytorch-examples-5dfeb46902baf444010f2f54bcf4dfbea109ae4d_GH0.tar.gz) = 7298483
diff --git a/science/linux-ai-ml-env/files/ai-ml-env-bash.in b/science/linux-ai-ml-env/files/ai-ml-env-bash.in
new file mode 100644
index 000000000000..cae2b877705b
--- /dev/null
+++ b/science/linux-ai-ml-env/files/ai-ml-env-bash.in
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+export LD_PRELOAD=%%LINUXBASE%%/usr/share/ai-ml-env/dummy-uvm.so
+export SSL_CERT_FILE=%%LINUXBASE%%/usr/lib/python3.9/site-packages/certifi/cacert.pem
+
+exec %%LINUXBASE%%/usr/bin/bash $*
diff --git a/science/linux-ai-ml-env/files/ai-ml-env-python.in b/science/linux-ai-ml-env/files/ai-ml-env-python.in
new file mode 100644
index 000000000000..335e571b2259
--- /dev/null
+++ b/science/linux-ai-ml-env/files/ai-ml-env-python.in
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+export LD_PRELOAD=%%DATADIR%%/dummy-uvm.so
+exec %%LINUXBASE%%/bin/python3 $*
diff --git a/science/linux-ai-ml-env/files/patch-reinforcement__learning_actor__critic.py b/science/linux-ai-ml-env/files/patch-reinforcement__learning_actor__critic.py
new file mode 100644
index 000000000000..64277c95cea6
--- /dev/null
+++ b/science/linux-ai-ml-env/files/patch-reinforcement__learning_actor__critic.py
@@ -0,0 +1,13 @@
+--- reinforcement_learning/actor_critic.py.orig	2025-02-09 16:56:58 UTC
++++ reinforcement_learning/actor_critic.py
+@@ -10,6 +10,10 @@ from torch.distributions import Categorical
+ import torch.optim as optim
+ from torch.distributions import Categorical
+ 
++# numpy.bool8 is deprecated since version 1.24.0
++if not hasattr(np, 'bool8'):
++    np.bool8 = np.bool_
++
+ # Cart Pole
+ 
+ parser = argparse.ArgumentParser(description='PyTorch actor-critic example')
diff --git a/science/linux-ai-ml-env/files/patch-reinforcement__learning_reinforce.py b/science/linux-ai-ml-env/files/patch-reinforcement__learning_reinforce.py
new file mode 100644
index 000000000000..9f1ab1540931
--- /dev/null
+++ b/science/linux-ai-ml-env/files/patch-reinforcement__learning_reinforce.py
@@ -0,0 +1,12 @@
+--- reinforcement_learning/reinforce.py.orig	2025-02-09 16:56:58 UTC
++++ reinforcement_learning/reinforce.py
+@@ -9,6 +9,9 @@ from torch.distributions import Categorical
+ import torch.optim as optim
+ from torch.distributions import Categorical
+ 
++# numpy.bool8 is deprecated since version 1.24.0
++if not hasattr(np, 'bool8'):
++    np.bool8 = np.bool_
+ 
+ parser = argparse.ArgumentParser(description='PyTorch REINFORCE example')
+ parser.add_argument('--gamma', type=float, default=0.99, metavar='G',
diff --git a/science/linux-ai-ml-env/files/patch-time__sequence__prediction_train.py b/science/linux-ai-ml-env/files/patch-time__sequence__prediction_train.py
new file mode 100644
index 000000000000..66a1b46c198b
--- /dev/null
+++ b/science/linux-ai-ml-env/files/patch-time__sequence__prediction_train.py
@@ -0,0 +1,11 @@
+--- time_sequence_prediction/train.py.orig	2025-02-09 16:56:58 UTC
++++ time_sequence_prediction/train.py
+@@ -44,7 +44,7 @@ if __name__ == '__main__':
+     np.random.seed(0)
+     torch.manual_seed(0)
+     # load data and make training set
+-    data = torch.load('traindata.pt')
++    data = torch.load('traindata.pt', weights_only=False)
+     input = torch.from_numpy(data[3:, :-1])
+     target = torch.from_numpy(data[3:, 1:])
+     test_input = torch.from_numpy(data[:3, :-1])
diff --git a/science/linux-ai-ml-env/files/patch-word__language__model_main.py b/science/linux-ai-ml-env/files/patch-word__language__model_main.py
new file mode 100644
index 000000000000..549b2f3b8b8b
--- /dev/null
+++ b/science/linux-ai-ml-env/files/patch-word__language__model_main.py
@@ -0,0 +1,11 @@
+--- word_language_model/main.py.orig	2025-03-17 17:25:58 UTC
++++ word_language_model/main.py
+@@ -243,7 +243,7 @@ with open(args.save, 'rb') as f:
+ 
+ # Load the best saved model.
+ with open(args.save, 'rb') as f:
+-    model = torch.load(f)
++    model = torch.load(f, weights_only=False)
+     # after load the rnn params are not a continuous chunk of memory
+     # this makes them a continuous chunk, and will speed up forward pass
+     # Currently, only rnn model supports flatten_parameters function.
diff --git a/science/linux-ai-ml-env/files/redundant-items.txt b/science/linux-ai-ml-env/files/redundant-items.txt
new file mode 100644
index 000000000000..54795ebaf9d0
--- /dev/null
+++ b/science/linux-ai-ml-env/files/redundant-items.txt
@@ -0,0 +1,41 @@
+bin/2to3-3.9
+bin/c_rehash
+bin/clear
+bin/idle3.9
+bin/infocmp
+bin/lzmadec
+bin/lzmainfo
+bin/ncursesw6-config
+bin/openssl
+bin/pip
+bin/pip3
+bin/pydoc3.9
+bin/python3.9
+bin/python3.9-config
+bin/sqlite3
+bin/sqlite3_analyzer
+bin/tabs
+bin/tclsh8.6
+bin/tic
+bin/toe
+bin/tput
+bin/tset
+bin/wheel
+bin/wish8.6
+bin/x86_64-conda-linux-gnu-ld
+bin/xz
+bin/xzdec
+bin/xzdiff
+bin/xzgrep
+bin/xzless
+bin/xzmore
+lib/python3.9/site-packages/_distutils_hack/
+lib/python3.9/site-packages/distutils-precedence.pth
+lib/python3.9/site-packages/pip-25.0.dist-info/
+lib/python3.9/site-packages/pip/
+lib/python3.9/site-packages/pkg_resources/
+lib/python3.9/site-packages/README.txt
+lib/python3.9/site-packages/setuptools-75.8.0-py3.9.egg-info/
+lib/python3.9/site-packages/setuptools/
+lib/python3.9/site-packages/wheel-0.45.1.dist-info/
+lib/python3.9/site-packages/wheel/
diff --git a/science/linux-ai-ml-env/files/requirements.txt b/science/linux-ai-ml-env/files/requirements.txt
new file mode 100644
index 000000000000..89aaddb5a303
--- /dev/null
+++ b/science/linux-ai-ml-env/files/requirements.txt
@@ -0,0 +1,56 @@
+accelerate==1.4.0
+certifi==2025.1.31
+charset-normalizer==3.4.1
+cloudpickle==3.1.1
+contourpy==1.3.0
+cycler==0.12.1
+diffusers==0.32.2
+filelock==3.17.0
+fonttools==4.56.0
+fsspec==2025.3.0
+gym==0.26.2
+gym-notices==0.0.8
+huggingface-hub==0.29.3
+idna==3.10
+importlib_metadata==8.6.1
+importlib_resources==6.5.2
+Jinja2==3.1.6
+kiwisolver==1.4.7
+MarkupSafe==3.0.2
+matplotlib==3.9.4
+mpmath==1.3.0
+networkx==3.2.1
+numpy==2.0.2
+nvidia-cublas-cu12==12.4.5.8
+nvidia-cuda-cupti-cu12==12.4.127
+nvidia-cuda-nvrtc-cu12==12.4.127
+nvidia-cuda-runtime-cu12==12.4.127
+nvidia-cudnn-cu12==9.1.0.70
+nvidia-cufft-cu12==11.2.1.3
+nvidia-curand-cu12==10.3.5.147
+nvidia-cusolver-cu12==11.6.1.9
+nvidia-cusparse-cu12==12.3.1.170
+nvidia-cusparselt-cu12==0.6.2
+nvidia-nccl-cu12==2.21.5
+nvidia-nvjitlink-cu12==12.4.127
+nvidia-nvtx-cu12==12.4.127
+packaging==24.2
+pillow==11.1.0
+psutil==7.0.0
+pyparsing==3.2.1
+python-dateutil==2.9.0.post0
+PyYAML==6.0.2
+regex==2024.11.6
+requests==2.32.3
+safetensors==0.5.3
+six==1.17.0
+sympy==1.13.1
+tokenizers==0.21.0
+torch==2.6.0
+torchvision==0.21.0
+tqdm==4.67.1
+transformers==4.49.0
+triton==3.2.0
+typing_extensions==4.12.2
+urllib3==2.3.0
+zipp==3.21.0
diff --git a/science/linux-ai-ml-env/files/stable-diffusion-sample.py b/science/linux-ai-ml-env/files/stable-diffusion-sample.py
new file mode 100644
index 000000000000..fae3f3af4513
--- /dev/null
+++ b/science/linux-ai-ml-env/files/stable-diffusion-sample.py
@@ -0,0 +1,24 @@
+import sys
+import torch
+from diffusers import StableDiffusionPipeline
+
+model_id = "CompVis/stable-diffusion-v1-4"
+device = "cuda" if torch.cuda.is_available() else "cpu"
+if device == "cpu":
+    print(
+        "CUDA is not available\n"
+        "Please ensure the following:\n"
+        "1. NVIDIA GPU is present in the system\n"
+        "2. NVIDIA Driver kernel module is loaded\n"
+        "3. dummy-uvm library is preloaded"
+        )
+    sys.exit(1)
+
+pipe = StableDiffusionPipeline.from_pretrained(model_id, torch_dtype=torch.float16)
+pipe = pipe.to(device)
+
+prompt = "a photo of an astronaut riding a horse on mars"
+image = pipe(prompt).images[0]
+
+image.save("astronaut_rides_horse.png")
+print(f"Image saved to astronaut_rides_horse.png")
diff --git a/science/linux-ai-ml-env/files/uvm_ioctl_override.c b/science/linux-ai-ml-env/files/uvm_ioctl_override.c
new file mode 100644
index 000000000000..843c8df762af
--- /dev/null
+++ b/science/linux-ai-ml-env/files/uvm_ioctl_override.c
@@ -0,0 +1,93 @@
+// Downloaded from https://gist.github.com/shkhln/40ef290463e78fb2b0000c60f4ad797e
+
+#define _GNU_SOURCE
+
+#include <assert.h>
+#include <dlfcn.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdio.h>
+
+// pkg install linux-c7-devtools
+// /compat/linux/bin/cc --sysroot=/compat/linux -m64 -std=c99 -Wall -ldl -fPIC -shared -o dummy-uvm.so uvm_ioctl_override.c
+// env LD_PRELOAD=$PWD/dummy-uvm.so <cmd>
+
+#define NV_UVM_INITIALIZE   0x30000001
+#define NV_UVM_DEINITIALIZE 0x30000002
+
+#define NV_ERR_NOT_SUPPORTED 0x56
+
+struct NvUvmInitParams
+{
+  uint64_t flags __attribute__((aligned(8)));
+  uint32_t status;
+};
+
+int (*libc_ioctl)(int fd, unsigned long request, ...) = NULL;
+
+int ioctl(int fd, unsigned long request, ...) {
+
+  if (!libc_ioctl) {
+    libc_ioctl = dlsym(RTLD_NEXT, "ioctl");
+  }
+
+  va_list _args_;
+  va_start(_args_, request);
+  void* data = va_arg(_args_, void*);
+  va_end(_args_);
+
+  if (request == NV_UVM_INITIALIZE) {
+    struct NvUvmInitParams* params = (struct NvUvmInitParams*)data;
+    params->status = NV_ERR_NOT_SUPPORTED;
+    return 0;
+  }
+
+  if (request == NV_UVM_DEINITIALIZE) {
+    return 0;
+  }
+
+  return libc_ioctl(fd, request, data);
+}
+
+int (*libc_open)(const char* path, int flags, ...) = NULL;
+
+int open(const char* path, int flags, ...) {
+
+  if (!libc_open) { libc_open = dlsym(RTLD_NEXT, "open"); }
+
+  mode_t mode = 0;
+
+  va_list _args_;
+  va_start(_args_, flags);
+
+  if (flags & O_CREAT) {
+    mode = va_arg(_args_, int);
+  }
+
+  va_end(_args_);
+
+  if (strcmp("/dev/nvidia-uvm", path) == 0) {
+    return libc_open("/dev/null", flags, mode);
+  }
+
+  return libc_open(path, flags, mode);
+}
+
+FILE* (*libc_fopen)(const char* path, const char* mode) = NULL;
+
+FILE* fopen(const char* path, const char* mode) {
+
+  if (!libc_fopen) { libc_fopen = dlsym(RTLD_NEXT, "fopen"); }
+
+  if (strncmp(path, "/proc/self/task/", sizeof("/proc/self/task/") - 1) == 0) {
+    char* tail = strchr(path + sizeof("/proc/self/task/"), '/');
+    if (tail != NULL && strcmp(tail, "/comm") == 0) {
+      assert(strcmp(mode, "wb") == 0);
+      return libc_fopen("/dev/null", mode);
+    }
+  }
+
+  return libc_fopen(path, mode);
+}
diff --git a/science/linux-ai-ml-env/pkg-descr b/science/linux-ai-ml-env/pkg-descr
new file mode 100644
index 000000000000..03dda5eb0c42
--- /dev/null
+++ b/science/linux-ai-ml-env/pkg-descr
@@ -0,0 +1,5 @@
+This port provides a Linux Python environment tailored for running Stable Diffusion models on NVIDIA GPUs. It includes:
+
+- A preconfigured Python environment with dependencies for Stable Diffusion and PyTorch examples.
+- PyTorch examples.
+- Sample scripts for running Stable Diffusion model and PyTorch examples.
diff --git a/science/linux-ai-ml-env/pkg-message b/science/linux-ai-ml-env/pkg-message
new file mode 100644
index 000000000000..4c744748c5c5
--- /dev/null
+++ b/science/linux-ai-ml-env/pkg-message
@@ -0,0 +1,32 @@
+[
+{ type: install
+  message: <<EOM
+To utilize CUDA support for PyTorch, both https://github.com/shkhln 's
+compatibility library preloading and Linux compatibility layer usage are
+required, as demonstrated in the provided demonstration scripts.
+
+To play with Stable Diffusion copy it to a user-writable directory, edit at will
+and launch it via ai-ml-env-python:
+
+	cp /usr/local/share/ai-ml-env/stable-diffusion-sample.py ~/
+	ai-ml-env-python stable-diffusion-sample.py
+
+This will download data packages into ~/.cache/huggingface/hub/ during the
+first-time run.
+
+The port also provides Pytorch examples from the official GitHub repository.
+To run and modify these examples, copy them to a user-writable directory
+and then launch the entry point script via ai-ml-env-bash:
+
+	cp -r /usr/local/share/ai-ml-env/pytorch-examples ~/pytorch-examples
+	cd ~/pytorch-examples && ai-ml-env-bash ./run_python_examples.sh
+
+You can then run
+
+ai-ml-env-bash ./run_python_examples.sh clean
+
+to remove downloaded data or just remove the whole directory to clean up
+everything.
+EOM
+}
+]
diff --git a/science/linux-ai-ml-env/pkg-plist b/science/linux-ai-ml-env/pkg-plist
new file mode 100644
index 000000000000..a0da7f0793eb
--- /dev/null
+++ b/science/linux-ai-ml-env/pkg-plist
@@ -0,0 +1,26 @@
+usr/bin/accelerate
+usr/bin/accelerate-config
+usr/bin/accelerate-estimate-memory
+usr/bin/accelerate-launch
+usr/bin/accelerate-merge-weights
+usr/bin/diffusers-cli
+usr/bin/f2py
+usr/bin/fonttools
+usr/bin/huggingface-cli
+usr/bin/isympy
+usr/bin/normalizer
+usr/bin/numpy-config
+usr/bin/proton
+usr/bin/proton-viewer
+usr/bin/pyftmerge
+usr/bin/pyftsubset
+usr/bin/torchfrtrace
+usr/bin/torchrun
+usr/bin/tqdm
+usr/bin/transformers-cli
+usr/bin/ttx
+%%DATADIR%%/dummy-uvm.so
+/usr/local/bin/ai-ml-env-bash
+/usr/local/bin/ai-ml-env-python
+/usr/local/share/ai-ml-env/stable-diffusion-sample.py
+@dir /usr/local/bin