PawinC commited on
Commit
520af46
·
0 Parent(s):

Duplicate from PawinC/Alpaca-Flask

Browse files
Files changed (11) hide show
  1. .env +2 -0
  2. .gitattributes +35 -0
  3. .gitignore +179 -0
  4. Dockerfile +23 -0
  5. README.md +11 -0
  6. client.py +30 -0
  7. dockerfile +23 -0
  8. main.py +122 -0
  9. requirements.txt +4 -0
  10. resources/ggml-model-q4_0.bin +3 -0
  11. resources/hashes.json +1 -0
.env ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ debugModeEnabled="True"
2
+ port="7860"
.gitattributes ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tar filter=lfs diff=lfs merge=lfs -text
29
+ *.tflite filter=lfs diff=lfs merge=lfs -text
30
+ *.tgz filter=lfs diff=lfs merge=lfs -text
31
+ *.wasm filter=lfs diff=lfs merge=lfs -text
32
+ *.xz filter=lfs diff=lfs merge=lfs -text
33
+ *.zip filter=lfs diff=lfs merge=lfs -text
34
+ *.zst filter=lfs diff=lfs merge=lfs -text
35
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
.gitignore ADDED
@@ -0,0 +1,179 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Created by https://www.toptal.com/developers/gitignore/api/python
2
+ # Edit at https://www.toptal.com/developers/gitignore?templates=python
3
+
4
+ Playground.ipynb
5
+ archive/
6
+
7
+ ### Python ###
8
+ # Byte-compiled / optimized / DLL files
9
+ __pycache__/
10
+ *.py[cod]
11
+ *$py.class
12
+
13
+ # C extensions
14
+ *.so
15
+
16
+ # Distribution / packaging
17
+ .Python
18
+ build/
19
+ develop-eggs/
20
+ dist/
21
+ downloads/
22
+ eggs/
23
+ .eggs/
24
+ lib/
25
+ lib64/
26
+ parts/
27
+ sdist/
28
+ var/
29
+ wheels/
30
+ share/python-wheels/
31
+ *.egg-info/
32
+ .installed.cfg
33
+ *.egg
34
+ MANIFEST
35
+
36
+ # PyInstaller
37
+ # Usually these files are written by a python script from a template
38
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
39
+ *.manifest
40
+ *.spec
41
+
42
+ # Installer logs
43
+ pip-log.txt
44
+ pip-delete-this-directory.txt
45
+
46
+ # Unit test / coverage reports
47
+ htmlcov/
48
+ .tox/
49
+ .nox/
50
+ .coverage
51
+ .coverage.*
52
+ .cache
53
+ nosetests.xml
54
+ coverage.xml
55
+ *.cover
56
+ *.py,cover
57
+ .hypothesis/
58
+ .pytest_cache/
59
+ cover/
60
+
61
+ # Translations
62
+ *.mo
63
+ *.pot
64
+
65
+ # Django stuff:
66
+ *.log
67
+ local_settings.py
68
+ db.sqlite3
69
+ db.sqlite3-journal
70
+
71
+ # Flask stuff:
72
+ instance/
73
+ .webassets-cache
74
+
75
+ # Scrapy stuff:
76
+ .scrapy
77
+
78
+ # Sphinx documentation
79
+ docs/_build/
80
+
81
+ # PyBuilder
82
+ .pybuilder/
83
+ target/
84
+
85
+ # Jupyter Notebook
86
+ .ipynb_checkpoints
87
+
88
+ # IPython
89
+ profile_default/
90
+ ipython_config.py
91
+
92
+ # pyenv
93
+ # For a library or package, you might want to ignore these files since the code is
94
+ # intended to run in multiple environments; otherwise, check them in:
95
+ # .python-version
96
+
97
+ # pipenv
98
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
99
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
100
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
101
+ # install all needed dependencies.
102
+ #Pipfile.lock
103
+
104
+ # poetry
105
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
106
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
107
+ # commonly ignored for libraries.
108
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
109
+ #poetry.lock
110
+
111
+ # pdm
112
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
113
+ #pdm.lock
114
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
115
+ # in version control.
116
+ # https://pdm.fming.dev/#use-with-ide
117
+ .pdm.toml
118
+
119
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
120
+ __pypackages__/
121
+
122
+ # Celery stuff
123
+ celerybeat-schedule
124
+ celerybeat.pid
125
+
126
+ # SageMath parsed files
127
+ *.sage.py
128
+
129
+ # Environments
130
+ .env
131
+ .venv
132
+ env/
133
+ venv/
134
+ ENV/
135
+ env.bak/
136
+ venv.bak/
137
+
138
+ # Spyder project settings
139
+ .spyderproject
140
+ .spyproject
141
+
142
+ # Rope project settings
143
+ .ropeproject
144
+
145
+ # mkdocs documentation
146
+ /site
147
+
148
+ # mypy
149
+ .mypy_cache/
150
+ .dmypy.json
151
+ dmypy.json
152
+
153
+ # Pyre type checker
154
+ .pyre/
155
+
156
+ # pytype static type analyzer
157
+ .pytype/
158
+
159
+ # Cython debug symbols
160
+ cython_debug/
161
+
162
+ # PyCharm
163
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
164
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
165
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
166
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
167
+ #.idea/
168
+
169
+ ### Python Patch ###
170
+ # Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration
171
+ poetry.toml
172
+
173
+ # ruff
174
+ .ruff_cache/
175
+
176
+ # LSP config files
177
+ pyrightconfig.json
178
+
179
+ # End of https://www.toptal.com/developers/gitignore/api/python
Dockerfile ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # read the doc: https://huggingface.co/docs/hub/spaces-sdks-docker
2
+ # you will also find guides on how best to write your Dockerfile
3
+
4
+ FROM python:3.9
5
+
6
+ WORKDIR /code
7
+
8
+ COPY ./requirements.txt /code/requirements.txt
9
+
10
+ RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
11
+
12
+ RUN useradd -m -u 1000 user
13
+
14
+ USER user
15
+
16
+ ENV HOME=/home/user \
17
+ PATH=/home/user/.local/bin:$PATH
18
+
19
+ WORKDIR $HOME/app
20
+
21
+ COPY --chown=user . $HOME/app
22
+
23
+ CMD ["python", "main.py"]
README.md ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Alpaca Flask
3
+ emoji: 🦙
4
+ colorFrom: purple
5
+ colorTo: indigo
6
+ sdk: docker
7
+ pinned: false
8
+ duplicated_from: PawinC/Alpaca-Flask
9
+ ---
10
+
11
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
client.py ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import time, requests
2
+
3
+ serverIsPreparing = True
4
+ print("Checking server status")
5
+ while serverIsPreparing:
6
+ try:
7
+ with requests.get("http://localhost:8080/chat") as r:
8
+ print("Status Check: " + r.text)
9
+ if r.text == 'Ready':
10
+ break
11
+ else:
12
+ time.sleep(5)
13
+ except requests.exceptions.ConnectionError:
14
+ print("Connection Refused. Retrying in 5 seconds.")
15
+ time.sleep(5)
16
+
17
+ print("Server is ready. Starting client.")
18
+ headers = {"Content-type": "application/json", "Authorization": "test:test"}
19
+ messages = [
20
+ {"role": "user", "content": "Hello, how are you feeling today?"},
21
+ {"role": "assistant", "content": "I'm feeling great. How about you?"},
22
+ {"role": "user", "content": "I'm fine, thanks for asking."}
23
+ ]
24
+
25
+ print("Sending Request...")
26
+ try:
27
+ with requests.post("http://localhost:8080/chat", headers=headers, json=messages) as r:
28
+ print(r.json()["content"])
29
+ except requests.exceptions.JSONDecodeError:
30
+ print(f"Something went wrong: {r.status_code}- {r.text}")
dockerfile ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # read the doc: https://huggingface.co/docs/hub/spaces-sdks-docker
2
+ # you will also find guides on how best to write your Dockerfile
3
+
4
+ FROM python:3.9
5
+
6
+ WORKDIR /code
7
+
8
+ COPY ./requirements.txt /code/requirements.txt
9
+
10
+ RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
11
+
12
+ RUN useradd -m -u 1000 user
13
+
14
+ USER user
15
+
16
+ ENV HOME=/home/user \
17
+ PATH=/home/user/.local/bin:$PATH
18
+
19
+ WORKDIR $HOME/app
20
+
21
+ COPY --chown=user . $HOME/app
22
+
23
+ CMD ["python", "main.py"]
main.py ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, render_template, request, abort, redirect, url_for, Response
2
+ from werkzeug.security import generate_password_hash, check_password_hash
3
+ from werkzeug.exceptions import HTTPException
4
+
5
+ import os, threading, json, waitress, datetime
6
+ from llama_cpp import Llama
7
+ from dotenv import load_dotenv
8
+ load_dotenv()
9
+
10
+ #Variables
11
+ DEBUGMODEENABLED = (os.getenv('debugModeEnabled', 'False') == 'True')
12
+ llm = None
13
+ AlpacaLoaded = False
14
+
15
+ #Chat Functions
16
+ def load_alpaca():
17
+ global llm, AlpacaLoaded
18
+ if not AlpacaLoaded:
19
+ print("Loading Alpaca...")
20
+ try:
21
+ llm = Llama(model_path="./resources/ggml-model-q4_0.bin", use_mmap=False, n_threads=2, verbose=False) #use_mlock=True
22
+ AlpacaLoaded = True
23
+ print("Done loading Alpaca.")
24
+ except AttributeError:
25
+ print("Error loading Alpaca. Please make sure you have the model file in the resources folder.")
26
+ else:
27
+ print("Alpaca already loaded.")
28
+
29
+ def getChatResponse(modelOutput):
30
+ return str(modelOutput["choices"][0]['message']['content'])
31
+
32
+
33
+ #Authentication Functions
34
+ def loadHashes():
35
+ global hashesDict
36
+ try:
37
+ with open("resources/hashes.json", "r") as f:
38
+ hashesDict = json.load(f)
39
+ except FileNotFoundError:
40
+ hashesDict = {}
41
+
42
+ def saveHashes():
43
+ global hashesDict
44
+ with open("resources/hashes.json", "w") as f:
45
+ json.dump(hashesDict, f)
46
+
47
+ def addHashes(username: str, password: str):
48
+ global hashesDict
49
+ hashesDict[username] = generate_password_hash(password, method='scrypt')
50
+ saveHashes()
51
+
52
+ def checkCredentials(username: str , password: str):
53
+ global hashesDict
54
+ if username in hashesDict:
55
+ return check_password_hash(hashesDict[username], password)
56
+ else:
57
+ return False
58
+
59
+ def verifyHeaders():
60
+ #Check + Obtain Authorization header
61
+ try:
62
+ user, passw = request.headers['Authorization'].split(":")
63
+ except (KeyError, ValueError):
64
+ abort(401)
65
+
66
+ #Check if Authorization header is valid
67
+ credentialsValid = checkCredentials(user, passw)
68
+ if not credentialsValid:
69
+ abort(403)
70
+ else:
71
+ return user
72
+
73
+
74
+ loadHashes()
75
+ #addHashes("test", "test")
76
+
77
+ #General Functions
78
+ def getIsoTime():
79
+ return str(datetime.datetime.now().isoformat())
80
+
81
+ #Flask App
82
+ app = Flask(__name__)
83
+
84
+ @app.route('/')
85
+ def main():
86
+ return """<!DOCTYPE HTML>
87
+ <html>
88
+ <head><meta name='color-scheme' content='dark'></head>
89
+ <body><p>Hello, World!</p></body>
90
+ </html>"""
91
+
92
+ @app.route('/chat', methods=['GET', 'POST'])
93
+ def chat():
94
+ if request.method == 'POST':
95
+ verifyHeaders()
96
+ print("Headers verified")
97
+ messages = request.get_json()
98
+ print("Got Message" + str(messages))
99
+
100
+ if AlpacaLoaded:
101
+ modelOutput = llm.create_chat_completion(messages=messages, max_tokens=128)
102
+ responseMessage = modelOutput["choices"][0]['message']
103
+ print(f"\n\nResponseMessage: {responseMessage}\n\n")
104
+ return Response(json.dumps(responseMessage, indent=2), content_type='application/json')
105
+ else:
106
+ abort(503, "Alpaca not loaded. Please wait a few seconds and try again.")
107
+ else:
108
+ return "Ready" if AlpacaLoaded else "Not Ready", 200 if AlpacaLoaded else 503
109
+
110
+ @app.errorhandler(HTTPException)
111
+ def handle_exception(e):
112
+ return Response({"error": f"{e.code} - {e.name}", "message": e.description}, content_type='application/json'), e.code
113
+
114
+ if __name__ == '__main__':
115
+ t = threading.Thread(target=load_alpaca, daemon=True).start()
116
+
117
+ port = int(os.getenv("port", "8080"))
118
+ print("Server successfully started.")
119
+ if DEBUGMODEENABLED:
120
+ app.run(host='0.0.0.0', port=port)
121
+ else:
122
+ waitress.serve(app, host='0.0.0.0', port=port, url_scheme='https')
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ flask
2
+ waitress
3
+ llama-cpp-python
4
+ python-dotenv
resources/ggml-model-q4_0.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:61d3f6cea80442f3c30e576540c95dc6d516c20e2002446ff278853a4cefdee9
3
+ size 3791729792
resources/hashes.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"test": "scrypt:32768:8:1$HBHtLz3s0Q8bmGFk$0af12bbd68d1b12498d64fc4508ccd848f183fbcfda1f0771788323776bbeeaa69316299228b8aa182f6601cab3c68567116ca5b2970a69538a331897510fef7"}