trying to install amd support
All checks were successful
Gitea Docker Redeploy / Redploy-App-on-self-via-SSH (push) Successful in 9m5s

This commit is contained in:
Tobias Weise 2024-09-02 16:35:15 +02:00
parent 2d227d438c
commit fc96b462a3
10 changed files with 231 additions and 140 deletions

View File

@ -1,28 +1,88 @@
FROM python:3.12 #FROM python:3.12
FROM ubuntu
RUN apt-get update RUN apt-get update
RUN apt-get install -y firefox-esr RUN apt-get install -y python3
RUN apt-get install -y python3-pip
#on debian:
#RUN apt-get install -y firefox-esr
RUN apt-get install -y firefox
RUN apt-get install -y ffmpeg RUN apt-get install -y ffmpeg
RUN apt-get install -y espeak RUN apt-get install -y espeak
RUN apt-get install -y flite RUN apt-get install -y flite
#COPY "amdgpu-install_6.1.60103-1_all.deb" "amdgpu-install_6.1.60103-1_all.deb"
#RUN dpkg -i "amdgpu-install_6.1.60103-1_all.deb"
#RUN amdgpu-install -y
#RUN apt-get -y install rocm-device-libs
#install "apt-add-repository" command:
RUN apt-get -y install software-properties-common dirmngr apt-transport-https lsb-release ca-certificates
RUN apt-add-repository -r ppa:graphics-drivers/ppa
RUN add-apt-repository ppa:oibaf/graphics-drivers
#RUN apt install hipsolver rocm-gdb -y
#RUN apt-get -y install wget
#RUN apt-get update -y --allow-unauthenticated
#RUN wget https://repo.radeon.com/amdgpu-install/6.1.1/ubuntu/jammy/amdgpu-install_6.1.60101-1_all.deb
#RUN apt-get install ./amdgpu-install_6.1.60101-1_all.deb -y
#RUN amdgpu-install --usecase=rocm
#RUN wget https://repo.radeon.com/amdgpu-install/6.1.1/ubuntu/jammy/amdgpu-install_6.1.60101-1_all.deb
#RUN apt install ./amdgpu-install_6.1.60101-1_all.deb -y
#RUN amdgpu-install --usecase=graphics,rocm -y
#RUN usermod -a -G render,video $LOGNAME
#RUN wget https://repo.radeon.com/amdgpu-install/6.1.1/ubuntu/jammy/amdgpu-install_6.1.60101-1_all.deb
#RUN apt install ./amdgpu-install_6.1.60101-1_all.deb -y
#RUN amdgpu-install --usecase=graphics,rocm -y
#RUN echo "deb http://deb.debian.org/debian/ bookworm main contrib non-free-firmware" > /etc/apt/sources.list
#RUN echo "deb http://deb.debian.org/debian/ bookworm main contrib non-free" > /etc/apt/sources.list
#RUN apt-add-repository contrib
#RUN apt-add-repository non-free
#RUN apt update -y
#RUN apt install nvidia-driver -y
#RUN apt-get install firmware-amd-graphics libgl1-mesa-dri libglx-mesa0 mesa-vulkan-drivers xserver-xorg-video-all -y
RUN apt-get update -y --allow-unauthenticated
RUN apt-get upgrade -y --allow-unauthenticated
RUN apt-get autoremove -y
RUN apt-get autoclean -y
#RUN curl https://ollama.ai/install.sh | sh #RUN curl https://ollama.ai/install.sh | sh
#RUN ollama run llama2 #RUN ollama run llama2
WORKDIR /code WORKDIR /code
COPY requirements.txt /code/requirements.txt COPY requirements.txt /code/requirements.txt
#RUN pip3 install --no-cache-dir --upgrade -r requirements.txt #RUN pip3 install --no-cache-dir --upgrade -r requirements.txt
RUN pip3 install --no-cache-dir -r requirements.txt
RUN pip3 install --no-cache-dir -r requirements.txt --break-system-packages
RUN pip3 freeze > current_requirements.txt RUN pip3 freeze > current_requirements.txt
COPY . . COPY . .
ENTRYPOINT ["python3", "/code/app.py"] ENTRYPOINT ["python3", "/code/app.py"]
#ENTRYPOINT ["fastapi", "run", "main.py", "--port", "8000"]
#gunicorn -w 4 -b 0.0.0.0 'hello:create_app()' #gunicorn -w 4 -b 0.0.0.0 'hello:create_app()'
#ENTRYPOINT ["gunicorn", "-w", "1", "-b", "0.0.0.0", "app:create_app()"] #ENTRYPOINT ["gunicorn", "-w", "1", "-b", "0.0.0.0", "app:create_app()"]
#ENTRYPOINT ["gunicorn", "-w", "1", "-b", "0.0.0.0:5000", "app:create_app()"] #ENTRYPOINT ["gunicorn", "-w", "1", "-b", "0.0.0.0:5000", "app:create_app()"]
#gunicorn app:app --worker-class eventlet -w 1 --bind 0.0.0.0:5000 --reload #gunicorn app:app --worker-class eventlet -w 1 --bind 0.0.0.0:5000 --reload
#ENTRYPOINT ["fastapi", "run", "main.py", "--port", "8000"]
#ENTRYPOINT ["uvicorn", "main:app", "--port", "8000", "--host", "0.0.0.0"]

Binary file not shown.

View File

@ -6,17 +6,16 @@ OpenAPI access via http://localhost:5000/openapi/ on local docker-compose deploy
#------std lib modules:------- #------std lib modules:-------
import os, sys, json, time import os, sys, json, time
import os.path import os.path
from typing import Any, Tuple, List, Dict, Any, Callable, Optional from typing import Any, Tuple, List, Dict, Any, Callable, Optional, Union
from datetime import datetime, date from datetime import datetime, date
#from collections import namedtuple import logging
import hashlib, traceback, logging
from functools import wraps from functools import wraps
import base64
#-------ext libs-------------- #-------ext libs--------------
from elasticsearch import NotFoundError, Elasticsearch # for normal read/write without vectors #from elasticsearch import NotFoundError, Elasticsearch # for normal read/write without vectors
from elasticsearch_dsl import Search, A, Document, Date, Integer, Keyword, Float, Long, Text, connections #from elasticsearch_dsl import A, Document, Date, Integer, Keyword, Float, Long, Text, connections
from elasticsearch_dsl import connections
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
import jwt as pyjwt import jwt as pyjwt
@ -172,10 +171,10 @@ def sockcon(data):
class SocketMessage(BaseModel): class SocketMessage(BaseModel):
room: str = Field(None, description="Status Code")
question: str = Field(None, description="Status Code") question: str = Field(None, description="Status Code")
system_prompt: str = Field(None, description="Status Code") system_prompt: str = Field(None, description="Status Code")
bot_id: str = Field(None, description="Status Code") bot_id: str = Field(None, description="Status Code")
room: Union[str, None] # = Field(None, description="Status Code")
#TODO: pydantic message type validation #TODO: pydantic message type validation

View File

@ -67,19 +67,11 @@ def get_type_schema():
def wait_for_elasticsearch(): def wait_for_elasticsearch():
#TODO: find a clean way to wait without exceptions!
#Wait for elasticsearch to start up!
#elastic_url = os.getenv("ELASTIC_URI")
#assert elastic_url
i = 1 i = 1
while True: while True:
try: try:
#client = Elasticsearch(hosts=elastic_url)
client = connections.get_connection() client = connections.get_connection()
client.indices.get_alias(index="*") client.indices.get_alias(index="*")
#connections.create_connection(hosts=app.config['elastic_uri'])
#connections.get_connection().cluster.health(wait_for_status='yellow')
#init_indicies()
print("Elasticsearch found! Run Flask-app!", flush=True) print("Elasticsearch found! Run Flask-app!", flush=True)
return return
except ConnectionError: except ConnectionError:

View File

@ -1,7 +1,6 @@
from smtplib import * from smtplib import *
from email.mime.text import MIMEText from email.mime.text import MIMEText
def send_mail(target_mail, subject, sender_mail, msg): def send_mail(target_mail, subject, sender_mail, msg):
msg = MIMEText(msg) msg = MIMEText(msg)

View File

@ -7,11 +7,9 @@ from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support import expected_conditions as EC
#from selenium.webdriver.chrome.options import Options #from selenium.webdriver.chrome.options import Options
from webdriver_manager.firefox import GeckoDriverManager from webdriver_manager.firefox import GeckoDriverManager
from selenium.webdriver.firefox.service import Service as FirefoxService from selenium.webdriver.firefox.service import Service as FirefoxService
from tempfile import mkdtemp from tempfile import mkdtemp
from time import sleep from time import sleep
from bs4 import BeautifulSoup from bs4 import BeautifulSoup

View File

@ -1,119 +1,151 @@
"""
OpenAPI access via http://localhost:5000/openapi/ on local docker-compose deployment
"""
#------std lib modules:-------
import os, sys, json, time
import os.path
from typing import Any, Tuple, List, Dict, Any, Callable, Optional
from datetime import datetime, date
import logging
from functools import wraps
#-------ext libs--------------
from elasticsearch_dsl import connections
from pydantic import BaseModel, Field
import jwt as pyjwt
import asyncio
#----------home grown--------------
from lib.funcs import group_by
from lib.elastictools import get_by_id, wait_for_elasticsearch
from lib.models import init_indicies, Chatbot, User, Text
from lib.chatbot import ask_bot, ask_bot2, train_text, download_llm
from lib.speech import text_to_speech
from lib.mail import send_mail
from lib.user import hash_password, create_user, create_default_users
from fastapi import FastAPI from fastapi import FastAPI
from fastapi.responses import HTMLResponse from fastapi.responses import HTMLResponse
from fastapi_socketio import SocketManager
from jinja2 import Environment, FileSystemLoader from jinja2 import Environment, FileSystemLoader
from pydantic import BaseModel
from neo4j import GraphDatabase
import os, sys
from multiprocessing import Pool
from bs4 import BeautifulSoup
import requests
from webbot import * #Bot, innerHTML
from xing import *
env = Environment(loader=FileSystemLoader('templates')) BOT_ROOT_PATH = os.getenv("BOT_ROOT_PATH")
assert BOT_ROOT_PATH
ollama_url = os.getenv("OLLAMA_URI")
assert ollama_url
elastic_url = os.getenv("ELASTIC_URI")
assert elastic_url
jwt_secret = os.getenv("SECRET")
assert jwt_secret
app = FastAPI() app = FastAPI()
socket_manager = SocketManager(app=app)
@app.sio.on('connect')
async def sockcon(sid, data):
"""
put every connection into it's own room
to avoid broadcasting messages
answer in callback only to room with sid
"""
room = request.sid + request.remote_addr
join_room(room)
await app.sio.emit('backend response', {'msg': f'Connected to room {room} !', "room": room}) # looks like iOS needs an answer
@app.sio.on('client message')
async def handle_message(sid, message):
#try:
room = message["room"]
question = message["question"]
system_prompt = message["system_prompt"]
bot_id = message["bot_id"]
start = datetime.now().timestamp()
d = ask_bot2(system_prompt + " " + question, bot_id)
def get_scores(*args):
score_docs = d["get_score_docs"]()
return score_docs
def do_streaming(*args):
start_stream = datetime.now().timestamp()
for chunk in d["answer_generator"]():
socket.emit('backend token', {'data': chunk, "done": False}, to=room)
stream_duration = round(datetime.now().timestamp() - start_stream, 2)
print("Stream duration: ", stream_duration, flush=True)
[score_docs, _] = await asyncio.gather(
asyncio.to_thread(get_scores, 1,2,3),
asyncio.to_thread(do_streaming, 1,2,3)
)
await app.sio.emit.emit('backend token', {
'done': True,
"score_docs": score_docs
}, to=room)
duration = round(datetime.now().timestamp() - start, 2)
print("Total duration: ", duration, flush=True)
#@app.sio.on('join')
#async def handle_join(sid, *args, **kwargs):
# await app.sio.emit('lobby', 'User joined')
#@sm.on('leave')
#async def handle_leave(sid, *args, **kwargs):
# await sm.emit('lobby', 'User left')
class JobSearch(BaseModel): class JobSearch(BaseModel):
location: str location: str
language: str language: str
def xing_job_search(location: str, radius: int) -> list:
with Bot() as bot:
vars_ = {
"page": 1,
"filter.industry%5B%5D": 90000,
"filter.type%5B%5D": "FULL_TIME",
"filter.level%5B%5D": 2,
"location": location,
"radius": radius
}
start_url = "https://www.xing.com/jobs/search?" + "&".join([k + "=" + str(v) for k, v in vars_.items()])
def kill_cookie_questions():
bot.click_id("consent-accept-button")
def next_page():
nav = bot.get_elements_by_tag_name("nav")[1]
next_site_link = get_elements_by_tag_name(nav, "a")[-1]
bot.click(next_site_link)
def get_nr_pages():
nav = bot.get_elements_by_tag_name("nav")[1]
return int(get_elements_by_tag_name(nav, "a")[-2].text)
def get_items():
rs = []
for article in bot.get_elements_by_tag_name("article"):
rs.append( get_children(article)[0].get_attribute("href") )
return rs
return collect_pagination_items(bot, start_url, next_page, get_nr_pages, get_items, kill_cookie_questions)
"""
pwd = "neo4j2"
proto = "bolt"
host = "192.168.99.101"
driver = GraphDatabase.driver("%s://%s:7687" % (proto, host), auth=("neo4j", pwd), encrypted=False)
def add_friend(tx, name, friend_name):
tx.run("MERGE (a:Person {name: $name}) "
"MERGE (a)-[:KNOWS]->(friend:Person {name: $friend_name})",
name=name, friend_name=friend_name)
def print_friends(tx, name):
for record in tx.run("MATCH (a:Person)-[:KNOWS]->(friend) WHERE a.name = $name "
"RETURN friend.name ORDER BY friend.name", name=name):
print(record["friend.name"])
with driver.session() as session:
session.write_transaction(add_friend, "Arthur", "Guinevere")
session.write_transaction(add_friend, "Arthur", "Lancelot")
session.write_transaction(add_friend, "Arthur", "Merlin")
session.read_transaction(print_friends, "Arthur")
driver.close()
"""
@app.post("/search") @app.post("/search")
def job_search(js: JobSearch): def job_search(js: JobSearch):
#https://berlinstartupjobs.com/?s=python&page=3 #https://berlinstartupjobs.com/?s=python&page=3
location = "Berlin" location = "Berlin"
radius = 50 radius = 50
with Bot() as bot:
vars_ = {
"page": 1,
"filter.industry%5B%5D": 90000,
"filter.type%5B%5D": "FULL_TIME",
"filter.level%5B%5D": 2,
"location": location,
"radius": radius
}
start_url = "https://www.xing.com/jobs/search?" + "&".join([k + "=" + str(v) for k, v in vars_.items()])
bot.set_url(start_url)
return bot.get_page_content()
@app.get("/") @app.get("/")

View File

@ -182,6 +182,8 @@
<!-- Buttons to Open the Modal --> <!-- Buttons to Open the Modal -->
<button id="register_btn" type="button" class="btn btn-secondary" data-bs-toggle="modal" data-bs-target="#registerModal">Register</button> <button id="register_btn" type="button" class="btn btn-secondary" data-bs-toggle="modal" data-bs-target="#registerModal">Register</button>
<br>
<br>
<button id="login_btn" type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#myModal">Login</button> <button id="login_btn" type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#myModal">Login</button>
<button id="logout_btn" type="button" class="btn btn-danger text-white">Logout</button> <button id="logout_btn" type="button" class="btn btn-danger text-white">Logout</button>
@ -270,11 +272,13 @@
</datalist> </datalist>
<button id="submit_btn" class="btn btn-success" type="button">Send</button> <button id="submit_btn" class="btn btn-success" type="button">Send</button>
</div> </div>
<div class="input-group">
<!-- Button to open the offcanvas sidebar -->
<button class="btn btn-light" type="button" data-bs-toggle="offcanvas" data-bs-target="#demo">
Settings...
</button>
</div>
<!-- Button to open the offcanvas sidebar -->
<button class="btn btn-light" type="button" data-bs-toggle="offcanvas" data-bs-target="#demo">
Settings...
</button>
</div> </div>
<div class="tab-pane container fade" id="create_bot_tab"> <div class="tab-pane container fade" id="create_bot_tab">

View File

@ -1,37 +1,39 @@
webdriver_manager webdriver_manager
requests requests==2.32.3
selenium selenium==4.23.1
bs4 bs4
elasticsearch elasticsearch==8.15.0
elasticsearch-dsl elasticsearch-dsl==8.15.1
ollama ollama==0.3.1
langchain langchain==0.2.14
langchain-community langchain-community==0.2.12
langchain_ollama langchain_ollama
langchain-elasticsearch langchain-elasticsearch==0.2.2
pydantic pydantic==2.8.2
uvicorn
fastapi==0.112.2
fastapi-socketio
fastapi gunicorn==23.0.0
Werkzeug==3.0.4
gunicorn
Werkzeug
flask flask
Flask-SocketIO Flask-SocketIO==5.3.6
flask-openapi3 flask-openapi3==3.1.3
minio minio==7.2.8
python-logging-loki python-logging-loki==0.3.1
pyjwt pyjwt
cryptography #cryptography==43.0.0
neo4j neo4j==5.23.1
pyttsx3 pyttsx3==2.91

View File

@ -70,6 +70,11 @@ services:
networks: networks:
- llm_network - llm_network
#command: "ollama pull llama2" #command: "ollama pull llama2"
devices:
#- /dev/dri/renderD128:/dev/dri/renderD128
#- /dev/fdk
- /dev/dri
#ollama-webui: #ollama-webui:
# container_name: ${APP_PREFIX}_ollama-webui # container_name: ${APP_PREFIX}_ollama-webui