Skip to content

Commit c07604a

Browse files
authored
Merge pull request lightspeed-core#852 from raptorsun/hermetic-arm-bis
LCORE-858: hermetic build with CPU torch
2 parents e24ea92 + c411ee5 commit c07604a

15 files changed

Lines changed: 6601 additions & 10 deletions

.tekton/lightspeed-stack-pull-request.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@ spec:
3030
- name: build-platforms
3131
value:
3232
- linux/x86_64
33+
- linux-c6gd2xlarge/arm64
34+
- name: build-source-image
35+
value: 'true'
36+
- name: prefetch-input
37+
value: '[{"type": "rpm", "path": "."}, {"type": "pip", "path": ".", "allow_binary": "true", "requirements_files": ["requirements.x86_64.txt", "requirements.aarch64.txt", "requirements.hermetic.txt", "requirements.torch.txt"]}]'
38+
- name: hermetic
39+
value: 'true'
3340
- name: dockerfile
3441
value: Containerfile
3542
pipelineSpec:
@@ -625,6 +632,9 @@ spec:
625632
optional: true
626633
- name: netrc
627634
optional: true
635+
timeouts:
636+
pipeline: 4h
637+
tasks: 4h
628638
taskRunTemplate:
629639
serviceAccountName: build-pipeline-lightspeed-stack
630640
workspaces:

.tekton/lightspeed-stack-push.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ spec:
2727
- name: build-platforms
2828
value:
2929
- linux/x86_64
30+
- linux-c6gd2xlarge/arm64
31+
- name: build-source-image
32+
value: 'true'
33+
- name: prefetch-input
34+
value: '[{"type": "rpm", "path": "."}, {"type": "pip", "path": ".", "allow_binary": "true", "requirements_files": ["requirements.x86_64.txt", "requirements.aarch64.txt", "requirements.hermetic.txt", "requirements.torch.txt"]}]'
35+
- name: hermetic
36+
value: 'true'
3037
- name: dockerfile
3138
value: Containerfile
3239
pipelineSpec:
@@ -622,6 +629,9 @@ spec:
622629
optional: true
623630
- name: netrc
624631
optional: true
632+
timeouts:
633+
pipeline: 4h
634+
tasks: 4h
625635
taskRunTemplate:
626636
serviceAccountName: build-pipeline-lightspeed-stack
627637
workspaces:

Containerfile

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,18 @@ RUN pip3.12 install "uv==0.8.15"
2222
# Add explicit files and directories
2323
# (avoid accidental inclusion of local directories or env files or credentials)
2424
COPY ${LSC_SOURCE_DIR}/src ./src
25-
COPY ${LSC_SOURCE_DIR}/pyproject.toml ${LSC_SOURCE_DIR}/LICENSE ${LSC_SOURCE_DIR}/README.md ${LSC_SOURCE_DIR}/uv.lock ./
25+
COPY ${LSC_SOURCE_DIR}/pyproject.toml ${LSC_SOURCE_DIR}/LICENSE ${LSC_SOURCE_DIR}/README.md ${LSC_SOURCE_DIR}/uv.lock ${LSC_SOURCE_DIR}/requirements.*.txt ./
2626

2727
# Bundle additional dependencies for library mode.
28-
RUN uv sync --locked --no-dev --group llslibdev
28+
# Source cachi2 environment for hermetic builds if available, otherwise use normal installation
29+
# cachi2.env has these env vars:
30+
# PIP_FIND_LINKS=/cachi2/output/deps/pip
31+
# PIP_NO_INDEX=true
32+
RUN if [ -f /cachi2/cachi2.env ]; then \
33+
. /cachi2/cachi2.env && uv venv --seed --no-index --find-links ${PIP_FIND_LINKS} && . .venv/bin/activate && pip install --no-index --find-links ${PIP_FIND_LINKS} -r requirements.$(uname -m).txt -r requirements.torch.txt; \
34+
else \
35+
uv sync --locked --no-dev --group llslibdev; \
36+
fi
2937

3038
# Explicitly remove some packages to mitigate some CVEs
3139
# - GHSA-wj6h-64fc-37mp: python-ecdsa package won't fix it upstream.

Makefile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ PATH_TO_PLANTUML := ~/bin
44
# Python registry to where the package should be uploaded
55
PYTHON_REGISTRY = pypi
66

7+
# PyTorch version
8+
TORCH_VERSION := 2.7.1
9+
710

811
run: ## Run the service locally
912
uv run src/lightspeed_stack.py
@@ -98,6 +101,13 @@ distribution-archives: ## Generate distribution archives to be uploaded into Pyt
98101
upload-distribution-archives: ## Upload distribution archives into Python registry
99102
uv run python -m twine upload --repository ${PYTHON_REGISTRY} dist/*
100103

104+
konflux-requirements: ## generate hermetic requirements.*.txt file for konflux build
105+
uv pip compile pyproject.toml -o requirements.x86_64.txt --generate-hashes --group llslibdev --python-platform x86_64-unknown-linux-gnu --torch-backend cpu --python-version 3.12
106+
uv pip compile pyproject.toml -o requirements.aarch64.txt --generate-hashes --group llslibdev --python-platform aarch64-unknown-linux-gnu --torch-backend cpu --python-version 3.12
107+
./scripts/remove_torch_deps.sh requirements.x86_64.txt
108+
./scripts/remove_torch_deps.sh requirements.aarch64.txt
109+
echo "torch==${TORCH_VERSION}" | uv pip compile - -o requirements.torch.txt --generate-hashes --python-version 3.12 --torch-backend cpu --emit-index-url --no-deps --index-url https://download.pytorch.org/whl/cpu
110+
101111
help: ## Show this help screen
102112
@echo 'Usage: make <OPTIONS> ... <TARGETS>'
103113
@echo ''

README.md

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,14 @@
99
[![Tag](https://img.shields.io/github/v/tag/lightspeed-core/lightspeed-stack)](https://github.com/lightspeed-core/lightspeed-stack/releases/tag/0.3.0)
1010

1111
Lightspeed Core Stack (LCS) is an AI-powered assistant that provides answers to product questions using backend LLM services, agents, and RAG databases.
12-
12+
1313
The service includes comprehensive user data collection capabilities for various types of user interaction data, which can be exported to Red Hat's Dataverse for analysis using the companion [lightspeed-to-dataverse-exporter](https://github.com/lightspeed-core/lightspeed-to-dataverse-exporter) service.
1414

1515

1616
<!-- vim-markdown-toc GFM -->
1717

18+
* [lightspeed-stack](#lightspeed-stack)
19+
* [About The Project](#about-the-project)
1820
* [Architecture](#architecture)
1921
* [Prerequisites](#prerequisites)
2022
* [Installation](#installation)
@@ -87,6 +89,11 @@ The service includes comprehensive user data collection capabilities for various
8789
* [Query endpoint REST API handler](#query-endpoint-rest-api-handler)
8890
* [Streaming query endpoint REST API handler](#streaming-query-endpoint-rest-api-handler)
8991
* [Versioning](#versioning)
92+
* [Konflux](#konflux)
93+
* [Updating Dependencies for Hermetic Builds](#updating-dependencies-for-hermetic-builds)
94+
* [When to Update Dependency Files](#when-to-update-dependency-files)
95+
* [Updating Python Dependencies](#updating-python-dependencies)
96+
* [Updating RPM Dependencies](#updating-rpm-dependencies)
9097

9198
<!-- vim-markdown-toc -->
9299

@@ -121,7 +128,7 @@ Lightspeed Core Stack is based on the FastAPI framework (Uvicorn). The service i
121128

122129
You will need an API key from one of these providers to run LightSpeed Stack.
123130

124-
For example, if you choose to use OpenAI:
131+
For example, if you choose to use OpenAI:
125132

126133
1. **Create an account** at [platform.openai.com](https://platform.openai.com)
127134
2. **Add payment information** (new accounts receive free trial credits)
@@ -141,7 +148,7 @@ Installation steps depends on operation system. Please look at instructions for
141148

142149
# Run LCS locally
143150

144-
To quickly get hands on LCS, we can run it using the default configurations provided in this repository:
151+
To quickly get hands on LCS, we can run it using the default configurations provided in this repository:
145152
0. install dependencies using [uv](https://docs.astral.sh/uv/getting-started/installation/) `uv sync --group dev --group llslibdev`
146153
1. check Llama stack settings in [run.yaml](run.yaml), make sure we can access the provider and the model, the server shoud listen to port 8321.
147154
2. export the LLM token env var that Llama stack requires. for OpenAI, we set the env var by `export OPENAI_API_KEY=sk-xxxxx`
@@ -156,7 +163,7 @@ To quickly get hands on LCS, we can run it using the default configurations prov
156163
157164
## LLM Compatibility
158165
159-
Lightspeed Core Stack (LCS) supports the large language models from the providers listed below.
166+
Lightspeed Core Stack (LCS) supports the large language models from the providers listed below.
160167
161168
| Provider | Model | Tool Calling | provider_type | Example |
162169
| -------- | ---------------------------------------------- | ------------ | -------------- | -------------------------------------------------------------------------- |
@@ -177,7 +184,7 @@ For details of OpenAI model capabilities, please refer to https://platform.opena
177184
178185
The LLM provider and model are set in the configuration file for Llama Stack. This repository has a Llama stack configuration file [run.yaml](examples/run.yaml) that can serve as a good example.
179186
180-
The LLM providers are set in the section `providers.inference`. This example adds a inference provider "openai" to the llama stack. To use environment variables as configuration values, we can use the syntax `${env.ENV_VAR_NAME}`.
187+
The LLM providers are set in the section `providers.inference`. This example adds a inference provider "openai" to the llama stack. To use environment variables as configuration values, we can use the syntax `${env.ENV_VAR_NAME}`.
181188
182189
For more details, please refer to [llama stack documentation](https://llama-stack.readthedocs.io/en/latest/distributions/configuration.html#providers). Here is a list of llamastack supported providers and their configuration details: [llama stack providers](https://llama-stack.readthedocs.io/en/latest/providers/inference/index.html#providers)
183190
@@ -847,7 +854,7 @@ the following form:
847854
[testpypi]
848855
username = __token__
849856
password = pypi-{your-API-token}
850-
857+
851858
[pypi]
852859
username = __token__
853860
password = pypi-{your-API-token}
@@ -969,3 +976,51 @@ The version X.Y.Z indicates:
969976
* X is the major version (backward-incompatible),
970977
* Y is the minor version (backward-compatible), and
971978
* Z is the patch version (backward-compatible bug fix).
979+
980+
# Konflux
981+
982+
The official image of Lightspeed Core Stack is built on [Konflux](https://konflux-ui.apps.kflux-prd-rh02.0fk9.p1.openshiftapps.com/ns/lightspeed-core-tenant/applications/lightspeed-stack).
983+
We have both x86_64 and ARM64 images.
984+
985+
## Updating Dependencies for Hermetic Builds
986+
987+
Konflux builds run in **hermetic mode** (air-gapped from the internet), so all dependencies must be prefetched and locked. When you add or update dependencies, you need to regenerate the lock files.
988+
989+
### When to Update Dependency Files
990+
991+
Update these files when you:
992+
- Add/remove/update Python packages in the project
993+
- Add/remove/update RPM packages in the Containerfile
994+
- Change the base image version
995+
996+
### Updating Python Dependencies
997+
998+
**Quick command:**
999+
```shell
1000+
make konflux-requirements
1001+
```
1002+
1003+
This generates three platform-specific requirements files:
1004+
- `requirements.x86_64.txt` - x86_64 packages (excludes torch)
1005+
- `requirements.aarch64.txt` - ARM64 packages (excludes torch)
1006+
- `requirements.torch.txt` - CPU variant of torch (shared by both platforms)
1007+
1008+
### Updating RPM Dependencies
1009+
1010+
**Prerequisites:** Install [rpm-lockfile-prototype](https://github.com/konflux-ci/rpm-lockfile-prototype?tab=readme-ov-file#installation)
1011+
1012+
**Steps:**
1013+
1014+
1. **List your RPM packages** in `rpms.in.yaml` under the `packages` field
1015+
1016+
2. **If you changed the base image**, extract its repo file:
1017+
```shell
1018+
podman run -it $BASE_IMAGE cat /etc/yum.repos.d/ubi.repo > ubi.repo
1019+
```
1020+
1021+
3. **Generate the lock file**:
1022+
```shell
1023+
rpm-lockfile-prototype --image $BASE_IMAGE rpms.in.yaml
1024+
```
1025+
1026+
This creates `rpms.lock.yaml` with pinned RPM versions.

pyproject.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,11 @@ Issues = "https://github.com/lightspeed-core/lightspeed-stack/issues"
8787
name = "pytorch-cpu"
8888
url = "https://download.pytorch.org/whl/cpu"
8989
explicit = true
90+
9091
[tool.uv.sources]
91-
torch = [{ index = "pytorch-cpu" }]
92+
torch = [
93+
{ index = "pytorch-cpu", group = "llslibdev" },
94+
]
9295

9396
[dependency-groups]
9497
dev = [

0 commit comments

Comments
 (0)