llm-studio / Makefile
qinfeng722's picture
Upload 17 files
d0b8972 verified
SHELL := /bin/bash
PYTHON_VERSION ?= 3.10
PYTHON ?= python$(PYTHON_VERSION)
PIP ?= $(PYTHON) -m pip
PIPENV ?= $(PYTHON) -m pipenv
PIPENV_PYTHON = $(PIPENV) run python
PIPENV_PIP = $(PIPENV_PYTHON) -m pip
PWD = $(shell pwd)
DOCKER_IMAGE ?= gcr.io/vorvan/h2oai/h2o-llmstudio:nightly
APP_VERSION=$(shell sed -n 's/^version = //p' pyproject.toml | tr -d '"')
ifeq ($(origin H2O_LLM_STUDIO_WORKDIR), environment)
WORKDIR := $(H2O_LLM_STUDIO_WORKDIR)
else
WORKDIR := $(shell pwd)
endif
ifeq ($(LOG_LEVEL), $(filter $(LOG_LEVEL), debug trace))
PW_DEBUG = DEBUG=pw:api
else
PW_DEBUG =
endif
.PHONY: pipenv
pipenv:
$(PIP) install pip==24.2
$(PIP) install pipenv==2024.0.1
.PHONY: setup
setup: pipenv
$(PIPENV) install --verbose --python $(PYTHON_VERSION)
-$(PIPENV_PIP) install flash-attn==2.6.1 --no-build-isolation --upgrade --no-cache-dir
.PHONY: setup-dev
setup-dev: pipenv
$(PIPENV) install --verbose --dev --python $(PYTHON_VERSION)
-$(PIPENV_PIP) install flash-attn==2.6.1 --no-build-isolation --upgrade --no-cache-dir
$(PIPENV) run playwright install
.PHONY: setup-no-flash
setup-no-flash: pipenv
$(PIPENV) install --verbose --python $(PYTHON_VERSION)
.PHONY: setup-conda-nightly
setup-conda:
@bash -c '\
set -e; \
source $$(conda info --base)/etc/profile.d/conda.sh; \
conda deactivate; \
conda create -n llmstudio python=3.10 -y; \
conda activate llmstudio; \
conda install -c nvidia/label/cuda-12.4.0 cuda-toolkit -y; \
conda install pytorch pytorch-cuda=12.4 -c pytorch-nightly -c nvidia -y; \
grep -v "nvidia" requirements.txt | grep -v "torch" | python -m pip install -r /dev/stdin; \
python -m pip install flash-attn==2.6.1 --no-build-isolation --upgrade --no-cache-dir; \
'
.PHONY: setup-ui
setup-ui: pipenv
$(PIPENV) install --verbose --categories=dev-packages --python $(PYTHON_VERSION)
$(PIPENV) run playwright install
.PHONY: export-requirements
export-requirements: pipenv
$(PIPENV) requirements > requirements.txt
clean-env:
$(PIPENV) --rm
clean-data:
rm -rf data
clean-output:
rm -rf output
reports:
mkdir -p reports
.PHONY: style
style: reports pipenv
@echo -n > reports/flake8_errors.log
@echo -n > reports/mypy_errors.log
@echo -n > reports/mypy.log
@echo
-$(PIPENV) run flake8 | tee -a reports/flake8_errors.log
@if [ -s reports/flake8_errors.log ]; then exit 1; fi
-$(PIPENV) run mypy . --check-untyped-defs | tee -a reports/mypy.log
@if ! grep -Eq "Success: no issues found in [0-9]+ source files" reports/mypy.log ; then exit 1; fi
.PHONY: format
format: pipenv
$(PIPENV) run isort .
$(PIPENV) run black .
.PHONY: isort
isort: pipenv
$(PIPENV) run isort .
.PHONY: black
black: pipenv
$(PIPENV) run black .
.PHONY: test
test: reports
@bash -c 'set -o pipefail; export PYTHONPATH=$(PWD); \
$(PIPENV) run pytest -v --junitxml=reports/junit.xml \
--import-mode importlib \
--html=./reports/pytest.html \
--cov=llm_studio \
--cov-report term \
--cov-report html:./reports/coverage.html \
-o log_cli=true -o log_level=INFO -o log_file=reports/tests.log \
tests/* 2>&1 | tee reports/tests.log'
# Use to quickly run a single test (e.g. make test-debug test=test_encode)
.PHONY: test-debug
test-debug: reports
@bash -c 'set -o pipefail; export PYTHONPATH=$(PWD); \
$(PIPENV) run pytest -v --junitxml=reports/junit.xml \
--import-mode importlib \
--html=./reports/pytest.html \
-k $(test) \
-s \
-o log_cli=false -o log_level=WARNING -o log_file=/dev/null \
tests/*'
# Only run the unit-tests (src)
.PHONY: test-unit
test-unit: reports
@bash -c 'set -o pipefail; export PYTHONPATH=$(PWD); \
$(PIPENV) run pytest -v --junitxml=reports/junit.xml \
--import-mode importlib \
--html=./reports/pytest.html \
-k src \
--cov=llm_studio/src \
--cov-report term \
--cov-report html:./reports/coverage.html \
-o log_cli=true -o log_level=INFO -o log_file=reports/tests.log \
tests/* 2>&1 | tee reports/tests.log'
.PHONY: test-ui
test-ui: reports setup-ui
@bash -c 'set -o pipefail; \
$(PW_DEBUG) $(PIPENV) run pytest \
-v \
--junitxml=reports/junit_ui.xml \
--html=./reports/pytest_ui.html \
-o log_cli=true \
-o log_level=$(LOG_LEVEL) \
-o log_file=reports/tests_ui.log \
tests/ui/test.py 2>&1 | tee reports/tests_ui.log'
.PHONY: test-ui-headed
test-ui-headed: setup-ui
$(PW_DEBUG) $(PIPENV) run pytest \
-vvs \
-s \
--headed \
--video=on \
--screenshot=on \
--slowmo=1000 \
tests/ui/test.py 2>&1 | tee reports/tests.log
.PHONY: test-ui-github-actions # Run UI tests in GitHub Actions. Starts the Wave server and runs the tests locally.
test-ui-github-actions: reports setup-ui
@echo "Starting the server..."
make llmstudio &
@echo "Server started in background."
@echo "Waiting 10s for the server to start..."
sleep 10
@echo "Running the tests..."
LOCAL_LOGIN=True \
PYTEST_BASE_URL=localhost:10101 \
make test-ui
@echo "Stopping the server..."
make stop-llmstudio
@echo "Server stopped."
.PHONY: wave
wave:
HF_HUB_DISABLE_TELEMETRY=1 \
H2O_WAVE_APP_ACCESS_KEY_ID=dev \
H2O_WAVE_APP_ACCESS_KEY_SECRET=dev \
H2O_WAVE_MAX_REQUEST_SIZE=25MB \
H2O_WAVE_NO_LOG=true \
H2O_WAVE_PRIVATE_DIR="/download/@$(WORKDIR)/output/download" \
$(PIPENV) run wave run llm_studio.app
.PHONY: llmstudio
llmstudio:
nvidia-smi && \
HF_HUB_DISABLE_TELEMETRY=1 \
H2O_WAVE_MAX_REQUEST_SIZE=25MB \
H2O_WAVE_NO_LOG=true \
H2O_WAVE_PRIVATE_DIR="/download/@$(WORKDIR)/output/download" \
$(PIPENV) run wave run --no-reload llm_studio.app
.PHONY: llmstudio-conda
llmstudio-conda:
CONDA_ACTIVATE="source $$(conda info --base)/etc/profile.d/conda.sh ; conda activate llmstudio" && \
bash -c "$$CONDA_ACTIVATE && \
nvidia-smi && \
HF_HUB_DISABLE_TELEMETRY=1 \
H2O_WAVE_MAX_REQUEST_SIZE=25MB \
H2O_WAVE_NO_LOG=true \
H2O_WAVE_PRIVATE_DIR="/download/@$(WORKDIR)/output/download" \
wave run --no-reload llm_studio.app"
.PHONY: stop-llmstudio
stop-llmstudio:
@kill $$(lsof -ti :10101)
.PHONY: docker-build-nightly
docker-build-nightly:
docker build -t $(DOCKER_IMAGE) .
# Run the Docker container with the nightly image
# Uses the local `llmstudio_mnt` directory as the mount point for the container
.PHONY: docker-run-nightly
docker-run-nightly:
ifeq (,$(wildcard ./llmstudio_mnt))
mkdir llmstudio_mnt
endif
docker run \
--runtime=nvidia \
--shm-size=64g \
--init \
--rm \
-it \
-u `id -u`:`id -g` \
-p 10101:10101 \
-v `pwd`/llmstudio_mnt:/home/llmstudio/mount \
$(DOCKER_IMAGE)
# Perform a local Trivy scan for CVEs
# Get Trivy from https://aquasecurity.github.io/trivy/v0.53/getting-started/installation/
.PHONY: trivy-local
trivy-local: docker-build-nightly
trivy image --scanners vuln --severity CRITICAL,HIGH --timeout 60m $(DOCKER_IMAGE)
.PHONY: docker-clean-all
docker-clean-all:
@CONTAINERS=$$(docker ps -a -q --filter ancestor=$(DOCKER_IMAGE)); \
if [ -n "$$CONTAINERS" ]; then \
docker stop $$CONTAINERS; \
docker rm $$CONTAINERS; \
fi
docker rmi $(DOCKER_IMAGE)
.PHONY: bundles
bundles:
rm -f -r bundles
mkdir -p bundles
cp -r static about.md bundles/
sed 's/{{VERSION}}/${APP_VERSION}/g' app.toml.template > bundles/app.toml
cd bundles && zip -r ai.h2o.llmstudio.${APP_VERSION}.wave *
.PHONY: shell
shell:
$(PIPENV) shell
setup-doc: # Install documentation dependencies
cd documentation && npm install
run-doc: # Run the doc locally
cd documentation && npm start
update-documentation-infrastructure:
cd documentation && npm update @h2oai/makersaurus
cd documentation && npm ls
build-doc-locally: # Bundles your website into static files for production
cd documentation && npm run build
serve-doc-locally: # Serves the built website locally
cd documentation && npm run serve