Refactor text2sql. (#1304)
Signed-off-by: Yao, Qing <qing.yao@intel.com> Signed-off-by: chensuyue <suyue.chen@intel.com>
This commit is contained in:
@@ -11,7 +11,7 @@ First of all, you need to build Docker Images locally. This step can be ignored
|
|||||||
```bash
|
```bash
|
||||||
git clone https://github.com/opea-project/GenAIComps.git
|
git clone https://github.com/opea-project/GenAIComps.git
|
||||||
cd GenAIComps
|
cd GenAIComps
|
||||||
docker build --no-cache -t opea/texttosql:comps -f comps/texttosql/langchain/Dockerfile .
|
docker build --no-cache -t opea/text2sql:comps -f comps/text2sql/src/Dockerfile .
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -21,13 +21,13 @@ Build the frontend Docker image based on react framework via below command:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd GenAIExamples/DBQnA/ui
|
cd GenAIExamples/DBQnA/ui
|
||||||
docker build --no-cache -t opea/texttosql-react-ui:latest -f docker/Dockerfile.react .
|
docker build --no-cache -t opea/text2sql-react-ui:latest -f docker/Dockerfile.react .
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Then run the command `docker images`, you will have the following Docker Images:
|
Then run the command `docker images`, you will have the following Docker Images:
|
||||||
|
|
||||||
1. `opea/texttosql:latest`
|
1. `opea/text2sql:latest`
|
||||||
2. `opea/dbqna-react-ui:latest`
|
2. `opea/dbqna-react-ui:latest`
|
||||||
|
|
||||||
## 🚀 Start Microservices
|
## 🚀 Start Microservices
|
||||||
@@ -62,7 +62,7 @@ export LLM_MODEL_ID="mistralai/Mistral-7B-Instruct-v0.3"
|
|||||||
export POSTGRES_USER=postgres
|
export POSTGRES_USER=postgres
|
||||||
export POSTGRES_PASSWORD=testpwd
|
export POSTGRES_PASSWORD=testpwd
|
||||||
export POSTGRES_DB=chinook
|
export POSTGRES_DB=chinook
|
||||||
export texttosql_port=9090
|
export text2sql_port=9090
|
||||||
```
|
```
|
||||||
|
|
||||||
Note: Please replace with `your_ip` with your external IP address, do not use localhost.
|
Note: Please replace with `your_ip` with your external IP address, do not use localhost.
|
||||||
@@ -90,14 +90,14 @@ We will use [Chinook](https://github.com/lerocha/chinook-database) sample databa
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|
||||||
docker run --name test-texttosql-postgres --ipc=host -e POSTGRES_USER=${POSTGRES_USER} -e POSTGRES_HOST_AUTH_METHOD=trust -e POSTGRES_DB=${POSTGRES_DB} -e POSTGRES_PASSWORD=${POSTGRES_PASSWORD} -p 5442:5432 -d -v $WORKPATH/comps/texttosql/langchain/chinook.sql:/docker-entrypoint-initdb.d/chinook.sql postgres:latest
|
docker run --name test-text2sql-postgres --ipc=host -e POSTGRES_USER=${POSTGRES_USER} -e POSTGRES_HOST_AUTH_METHOD=trust -e POSTGRES_DB=${POSTGRES_DB} -e POSTGRES_PASSWORD=${POSTGRES_PASSWORD} -p 5442:5432 -d -v $WORKPATH/comps/text2sql/langchain/chinook.sql:/docker-entrypoint-initdb.d/chinook.sql postgres:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
- Start TGI Service
|
- Start TGI Service
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|
||||||
docker run -d --name="test-texttosql-tgi-endpoint" --ipc=host -p $TGI_PORT:80 -v ./data:/data --shm-size 1g -e HUGGINGFACEHUB_API_TOKEN=${HUGGINGFACEHUB_API_TOKEN} -e HF_TOKEN=${HF_TOKEN} -e model=${model} ghcr.io/huggingface/text-generation-inference:2.1.0 --model-id $model
|
docker run -d --name="test-text2sql-tgi-endpoint" --ipc=host -p $TGI_PORT:80 -v ./data:/data --shm-size 1g -e HUGGINGFACEHUB_API_TOKEN=${HUGGINGFACEHUB_API_TOKEN} -e HF_TOKEN=${HF_TOKEN} -e model=${model} ghcr.io/huggingface/text-generation-inference:2.1.0 --model-id $model
|
||||||
```
|
```
|
||||||
|
|
||||||
- Start Text-to-SQL Service
|
- Start Text-to-SQL Service
|
||||||
@@ -105,7 +105,7 @@ docker run -d --name="test-texttosql-tgi-endpoint" --ipc=host -p $TGI_PORT:80 -v
|
|||||||
```bash
|
```bash
|
||||||
unset http_proxy
|
unset http_proxy
|
||||||
|
|
||||||
docker run -d --name="test-texttosql-server" --ipc=host -p ${texttosql_port}:8090 --ipc=host -e http_proxy=$http_proxy -e https_proxy=$https_proxy -e TGI_LLM_ENDPOINT=$TGI_LLM_ENDPOINT opea/texttosql:latest
|
docker run -d --name="test-text2sql-server" --ipc=host -p ${text2sql_port}:8090 --ipc=host -e http_proxy=$http_proxy -e https_proxy=$https_proxy -e TGI_LLM_ENDPOINT=$TGI_LLM_ENDPOINT opea/text2sql:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
- Start React UI service
|
- Start React UI service
|
||||||
@@ -141,7 +141,7 @@ curl --location http://${your_ip}:9090/v1/postgres/health \
|
|||||||
#### 3.2.2 Invoke the microservice.
|
#### 3.2.2 Invoke the microservice.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl http://${your_ip}:9090/v1/texttosql\
|
curl http://${your_ip}:9090/v1/text2sql\
|
||||||
-X POST \
|
-X POST \
|
||||||
-d '{"input_text": "Find the total number of Albums.","conn_str": {"user": "'${POSTGRES_USER}'","password": "'${POSTGRES_PASSWORD}'","host": "'${your_ip}'", "port": "5442", "database": "'${POSTGRES_DB}'"}}' \
|
-d '{"input_text": "Find the total number of Albums.","conn_str": {"user": "'${POSTGRES_USER}'","password": "'${POSTGRES_PASSWORD}'","host": "'${your_ip}'", "port": "5442", "database": "'${POSTGRES_DB}'"}}' \
|
||||||
-H 'Content-Type: application/json'
|
-H 'Content-Type: application/json'
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ services:
|
|||||||
no_proxy: ${no_proxy}
|
no_proxy: ${no_proxy}
|
||||||
http_proxy: ${http_proxy}
|
http_proxy: ${http_proxy}
|
||||||
https_proxy: ${https_proxy}
|
https_proxy: ${https_proxy}
|
||||||
HF_TOKEN: ${HF_TOKEN}
|
HF_TOKEN: ${HUGGINGFACEHUB_API_TOKEN}
|
||||||
|
HUGGINGFACEHUB_API_TOKEN: ${HUGGINGFACEHUB_API_TOKEN}
|
||||||
shm_size: 1g
|
shm_size: 1g
|
||||||
command: --model-id ${LLM_MODEL_ID}
|
command: --model-id ${LLM_MODEL_ID}
|
||||||
|
|
||||||
@@ -32,19 +33,19 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- ./chinook.sql:/docker-entrypoint-initdb.d/chinook.sql
|
- ./chinook.sql:/docker-entrypoint-initdb.d/chinook.sql
|
||||||
|
|
||||||
texttosql-service:
|
text2sql-service:
|
||||||
image: opea/texttosql:latest
|
image: ${REGISTRY:-opea}/text2sql:${TAG:-latest}
|
||||||
container_name: texttosql-service
|
container_name: text2sql-service
|
||||||
ports:
|
ports:
|
||||||
- "9090:8090"
|
- "9090:8080"
|
||||||
environment:
|
environment:
|
||||||
- TGI_LLM_ENDPOINT=${TGI_LLM_ENDPOINT}
|
- TGI_LLM_ENDPOINT=${TGI_LLM_ENDPOINT}
|
||||||
|
|
||||||
dbqna-xeon-react-ui-server:
|
dbqna-xeon-react-ui-server:
|
||||||
image: opea/dbqna-react-ui:latest
|
image: ${REGISTRY:-opea}/text2sql-react-ui:${TAG:-latest}
|
||||||
container_name: dbqna-xeon-react-ui-server
|
container_name: dbqna-xeon-react-ui-server
|
||||||
depends_on:
|
depends_on:
|
||||||
- texttosql-service
|
- text2sql-service
|
||||||
ports:
|
ports:
|
||||||
- "5174:80"
|
- "5174:80"
|
||||||
environment:
|
environment:
|
||||||
|
|||||||
@@ -2,16 +2,16 @@
|
|||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
services:
|
services:
|
||||||
texttosql:
|
text2sql:
|
||||||
build:
|
build:
|
||||||
context: GenAIComps
|
context: GenAIComps
|
||||||
dockerfile: comps/texttosql/langchain/Dockerfile
|
dockerfile: comps/text2sql/src/Dockerfile
|
||||||
args:
|
args:
|
||||||
http_proxy: ${http_proxy}
|
http_proxy: ${http_proxy}
|
||||||
https_proxy: ${https_proxy}
|
https_proxy: ${https_proxy}
|
||||||
no_proxy: ${no_proxy}
|
no_proxy: ${no_proxy}
|
||||||
image: ${REGISTRY:-opea}/texttosql:${TAG:-latest}
|
image: ${REGISTRY:-opea}/text2sql:${TAG:-latest}
|
||||||
texttosql-react-ui:
|
text2sql-react-ui:
|
||||||
build:
|
build:
|
||||||
context: ../ui
|
context: ../ui
|
||||||
dockerfile: ./docker/Dockerfile.react
|
dockerfile: ./docker/Dockerfile.react
|
||||||
@@ -19,4 +19,4 @@ services:
|
|||||||
http_proxy: ${http_proxy}
|
http_proxy: ${http_proxy}
|
||||||
https_proxy: ${https_proxy}
|
https_proxy: ${https_proxy}
|
||||||
no_proxy: ${no_proxy}
|
no_proxy: ${no_proxy}
|
||||||
image: ${REGISTRY:-opea}/texttosql-react-ui:${TAG:-latest}
|
image: ${REGISTRY:-opea}/text2sql-react-ui:${TAG:-latest}
|
||||||
|
|||||||
@@ -4,66 +4,54 @@
|
|||||||
|
|
||||||
set -xe
|
set -xe
|
||||||
|
|
||||||
|
IMAGE_REPO=${IMAGE_REPO:-"opea"}
|
||||||
|
IMAGE_TAG=${IMAGE_TAG:-"latest"}
|
||||||
|
echo "REGISTRY=IMAGE_REPO=${IMAGE_REPO}"
|
||||||
|
echo "TAG=IMAGE_TAG=${IMAGE_TAG}"
|
||||||
|
export REGISTRY=${IMAGE_REPO}
|
||||||
|
export TAG=${IMAGE_TAG}
|
||||||
|
|
||||||
WORKPATH=$(dirname "$PWD")
|
WORKPATH=$(dirname "$PWD")
|
||||||
LOG_PATH="$WORKPATH/tests"
|
LOG_PATH="$WORKPATH/tests"
|
||||||
ip_address=$(hostname -I | awk '{print $1}')
|
ip_address=$(hostname -I | awk '{print $1}')
|
||||||
tgi_port=8008
|
tgi_port=8008
|
||||||
tgi_volume=$WORKPATH/data
|
|
||||||
|
|
||||||
export model="meta-llama/Meta-Llama-3-8B-Instruct"
|
|
||||||
export HUGGINGFACEHUB_API_TOKEN=${HUGGINGFACEHUB_API_TOKEN}
|
|
||||||
export POSTGRES_USER=postgres
|
|
||||||
export POSTGRES_PASSWORD=testpwd
|
|
||||||
export POSTGRES_DB=chinook
|
|
||||||
export TEXTTOSQL_PORT=9090
|
|
||||||
export TGI_LLM_ENDPOINT="http://${ip_address}:${tgi_port}"
|
|
||||||
|
|
||||||
|
|
||||||
function build_docker_images() {
|
function build_docker_images() {
|
||||||
echo $WORKPATH
|
cd $WORKPATH/docker_image_build
|
||||||
OPEAPATH=$(realpath "$WORKPATH/../..")
|
git clone https://github.com/opea-project/GenAIComps.git && cd GenAIComps && git checkout "${opea_branch:-"main"}" && cd ../
|
||||||
|
|
||||||
echo "Building Text to Sql service..."
|
|
||||||
cd $OPEAPATH
|
|
||||||
rm -rf GenAIComps/
|
|
||||||
git clone https://github.com/opea-project/GenAIComps.git
|
|
||||||
cd $OPEAPATH/GenAIComps
|
|
||||||
docker build --no-cache -t opea/texttosql:latest -f comps/texttosql/langchain/Dockerfile .
|
|
||||||
|
|
||||||
echo "Building React UI service..."
|
|
||||||
cd $OPEAPATH/GenAIExamples/DBQnA/ui
|
|
||||||
docker build --no-cache -t opea/dbqna-react-ui:latest -f docker/Dockerfile.react .
|
|
||||||
|
|
||||||
|
echo "Build all the images with --no-cache, check docker_image_build.log for details..."
|
||||||
|
docker compose -f build.yaml build --no-cache > ${LOG_PATH}/docker_image_build.log
|
||||||
}
|
}
|
||||||
|
|
||||||
function start_service() {
|
function start_service() {
|
||||||
|
cd $WORKPATH/docker_compose/intel/cpu/xeon
|
||||||
|
export model="mistralai/Mistral-7B-Instruct-v0.3"
|
||||||
|
export LLM_MODEL_ID=${model}
|
||||||
|
export HUGGINGFACEHUB_API_TOKEN=${HUGGINGFACEHUB_API_TOKEN}
|
||||||
|
export POSTGRES_USER=postgres
|
||||||
|
export POSTGRES_PASSWORD=testpwd
|
||||||
|
export POSTGRES_DB=chinook
|
||||||
|
export TEXT2SQL_PORT=9090
|
||||||
|
export TGI_LLM_ENDPOINT="http://${ip_address}:${tgi_port}"
|
||||||
|
|
||||||
docker run --name test-texttosql-postgres --ipc=host -e POSTGRES_USER=${POSTGRES_USER} -e POSTGRES_HOST_AUTH_METHOD=trust -e POSTGRES_DB=${POSTGRES_DB} -e POSTGRES_PASSWORD=${POSTGRES_PASSWORD} -p 5442:5432 -d -v $WORKPATH/docker_compose/intel/cpu/xeon/chinook.sql:/docker-entrypoint-initdb.d/chinook.sql postgres:latest
|
# Start Docker Containers
|
||||||
|
docker compose -f compose.yaml up -d > ${LOG_PATH}/start_services_with_compose.log
|
||||||
docker run -d --name="test-texttosql-tgi-endpoint" --ipc=host -p $tgi_port:80 -v ./data:/data --shm-size 1g -e HUGGINGFACEHUB_API_TOKEN=${HUGGINGFACEHUB_API_TOKEN} -e HF_TOKEN=${HUGGINGFACEHUB_API_TOKEN} -e model=${model} ghcr.io/huggingface/text-generation-inference:2.1.0 --model-id $model
|
|
||||||
|
|
||||||
|
|
||||||
docker run -d --name="test-texttosql-server" --ipc=host -p $TEXTTOSQL_PORT:8090 --ipc=host -e http_proxy=$http_proxy -e https_proxy=$https_proxy -e TGI_LLM_ENDPOINT=$TGI_LLM_ENDPOINT opea/texttosql:latest
|
|
||||||
|
|
||||||
# check whether tgi is fully ready.
|
# check whether tgi is fully ready.
|
||||||
n=0
|
n=0
|
||||||
until [[ "$n" -ge 100 ]] || [[ $ready == true ]]; do
|
until [[ "$n" -ge 100 ]] || [[ $ready == true ]]; do
|
||||||
docker logs test-texttosql-tgi-endpoint > ${LOG_PATH}/tgi.log
|
docker logs tgi-service > ${LOG_PATH}/tgi.log
|
||||||
n=$((n+1))
|
n=$((n+1))
|
||||||
if grep -q Connected ${LOG_PATH}/tgi.log; then
|
if grep -q Connected ${LOG_PATH}/tgi.log; then
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
sleep 5s
|
sleep 5s
|
||||||
done
|
done
|
||||||
sleep 5s
|
|
||||||
|
|
||||||
# Run the UI container
|
|
||||||
docker run -d --name="test-dbqna-react-ui-server" --ipc=host -p 5174:80 -e no_proxy=$no_proxy -e https_proxy=$https_proxy -e http_proxy=$http_proxy opea/dbqna-react-ui:latest
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function validate_microservice() {
|
function validate_microservice() {
|
||||||
result=$(http_proxy="" curl --connect-timeout 5 --max-time 120000 http://${ip_address}:$TEXTTOSQL_PORT/v1/texttosql\
|
result=$(http_proxy="" curl --connect-timeout 5 --max-time 120000 http://${ip_address}:$TEXT2SQL_PORT/v1/text2sql\
|
||||||
-X POST \
|
-X POST \
|
||||||
-d '{"input_text": "Find the total number of Albums.","conn_str": {"user": "'${POSTGRES_USER}'","password": "'${POSTGRES_PASSWORD}'","host": "'${ip_address}'", "port": "5442", "database": "'${POSTGRES_DB}'" }}' \
|
-d '{"input_text": "Find the total number of Albums.","conn_str": {"user": "'${POSTGRES_USER}'","password": "'${POSTGRES_PASSWORD}'","host": "'${ip_address}'", "port": "5442", "database": "'${POSTGRES_DB}'" }}' \
|
||||||
-H 'Content-Type: application/json')
|
-H 'Content-Type: application/json')
|
||||||
@@ -73,8 +61,8 @@ function validate_microservice() {
|
|||||||
echo "Result correct."
|
echo "Result correct."
|
||||||
else
|
else
|
||||||
echo "Result wrong. Received was $result"
|
echo "Result wrong. Received was $result"
|
||||||
docker logs test-texttosql-server > ${LOG_PATH}/texttosql.log
|
docker logs text2sql-service > ${LOG_PATH}/text2sql.log
|
||||||
docker logs test-texttosql-tgi-endpoint > ${LOG_PATH}/tgi.log
|
docker logs tgi-service > ${LOG_PATH}/tgi.log
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -110,8 +98,8 @@ function validate_frontend() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function stop_docker() {
|
function stop_docker() {
|
||||||
cid=$(docker ps -aq --filter "name=test-*")
|
cd $WORKPATH/docker_compose/intel/cpu/xeon
|
||||||
if [[ ! -z "$cid" ]]; then docker stop $cid && docker rm $cid && sleep 1s; fi
|
docker compose stop && docker compose rm -f
|
||||||
}
|
}
|
||||||
|
|
||||||
function main() {
|
function main() {
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ const getHostIP = () => {
|
|||||||
test('testing api with dynamic host', async () => {
|
test('testing api with dynamic host', async () => {
|
||||||
// Get the dynamic host IP
|
// Get the dynamic host IP
|
||||||
const host = await getHostIP();
|
const host = await getHostIP();
|
||||||
const endpointUrl = `http://${host}:9090/v1/texttosql`;
|
const endpointUrl = `http://${host}:9090/v1/text2sql`;
|
||||||
|
|
||||||
const formData = {
|
const formData = {
|
||||||
user: 'postgres',
|
user: 'postgres',
|
||||||
@@ -43,9 +43,10 @@ test('testing api with dynamic host', async () => {
|
|||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
|
|
||||||
const result = response.data.result;
|
const result = response.data.result;
|
||||||
|
console.log(result);
|
||||||
expect(result.hasOwnProperty('sql')).toBe(true);
|
expect(result.hasOwnProperty('sql')).toBe(true);
|
||||||
expect(result.hasOwnProperty('output')).toBe(true);
|
expect(result.hasOwnProperty('output')).toBe(true);
|
||||||
expect(result.hasOwnProperty('input')).toBe(true);
|
expect(result.hasOwnProperty('input')).toBe(true);
|
||||||
expect(result.input).toBe(question);
|
expect(result.input.input_text).toBe(question);
|
||||||
|
|
||||||
}, apiTimeOutInSeconds * 1000);
|
}, apiTimeOutInSeconds * 1000);
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ const DBConnect: React.FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let api_response: Record<string, any>;
|
let api_response: Record<string, any>;
|
||||||
api_response = await axios.post(`${TEXT_TO_SQL_URL}/texttosql`, payload);
|
api_response = await axios.post(`${TEXT_TO_SQL_URL}/text2sql`, payload);
|
||||||
|
|
||||||
setSqlQuery(api_response.data.result.sql); // Assuming the API returns an SQL query
|
setSqlQuery(api_response.data.result.sql); // Assuming the API returns an SQL query
|
||||||
setQueryOutput(api_response.data.result.output);
|
setQueryOutput(api_response.data.result.output);
|
||||||
@@ -163,7 +163,7 @@ const DBConnect: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* DBQnA Section */}
|
{/* DBQnA Section */}
|
||||||
<div className={styleClasses.textToSQLSection}>
|
<div className={styleClasses.text2SQLSection}>
|
||||||
<Title order={1}>DBQnA</Title>
|
<Title order={1}>DBQnA</Title>
|
||||||
{isConnected && (
|
{isConnected && (
|
||||||
<form className={styleClasses.form} onSubmit={handleGenerateSQL}>
|
<form className={styleClasses.form} onSubmit={handleGenerateSQL}>
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.dbConnectSection,
|
.dbConnectSection,
|
||||||
.textToSQLSection {
|
.text2SQLSection {
|
||||||
flex: 1; /* Allow each section to take up equal space */
|
flex: 1; /* Allow each section to take up equal space */
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
|
|||||||
Reference in New Issue
Block a user