Spaces:
Running
on
Zero
Running
on
Zero
First commit
Browse files- .gitignore +173 -0
- .gitlint +143 -0
- .pre-commit-config.yaml +51 -0
- poetry.lock +0 -0
- pyproject.toml +61 -0
- requirements.txt +77 -0
- src/app.css +75 -0
- src/app.py +392 -0
- src/app_head.html +16 -0
- src/themes/carbon.py +147 -0
- src/themes/research_monochrome.py +152 -0
.gitignore
ADDED
@@ -0,0 +1,173 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Byte-compiled / optimized / DLL files
|
2 |
+
__pycache__/
|
3 |
+
*.py[cod]
|
4 |
+
*$py.class
|
5 |
+
|
6 |
+
# C extensions
|
7 |
+
*.so
|
8 |
+
|
9 |
+
# Distribution / packaging
|
10 |
+
.Python
|
11 |
+
build/
|
12 |
+
develop-eggs/
|
13 |
+
dist/
|
14 |
+
downloads/
|
15 |
+
eggs/
|
16 |
+
.eggs/
|
17 |
+
lib/
|
18 |
+
lib64/
|
19 |
+
parts/
|
20 |
+
sdist/
|
21 |
+
var/
|
22 |
+
wheels/
|
23 |
+
share/python-wheels/
|
24 |
+
*.egg-info/
|
25 |
+
.installed.cfg
|
26 |
+
*.egg
|
27 |
+
MANIFEST
|
28 |
+
|
29 |
+
# PyInstaller
|
30 |
+
# Usually these files are written by a python script from a template
|
31 |
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
32 |
+
*.manifest
|
33 |
+
*.spec
|
34 |
+
|
35 |
+
# Installer logs
|
36 |
+
pip-log.txt
|
37 |
+
pip-delete-this-directory.txt
|
38 |
+
|
39 |
+
# Unit test / coverage reports
|
40 |
+
htmlcov/
|
41 |
+
.tox/
|
42 |
+
.nox/
|
43 |
+
.coverage
|
44 |
+
.coverage.*
|
45 |
+
.cache
|
46 |
+
nosetests.xml
|
47 |
+
coverage.xml
|
48 |
+
*.cover
|
49 |
+
*.py,cover
|
50 |
+
.hypothesis/
|
51 |
+
.pytest_cache/
|
52 |
+
cover/
|
53 |
+
|
54 |
+
# Translations
|
55 |
+
*.mo
|
56 |
+
*.pot
|
57 |
+
|
58 |
+
# Django stuff:
|
59 |
+
*.log
|
60 |
+
local_settings.py
|
61 |
+
db.sqlite3
|
62 |
+
db.sqlite3-journal
|
63 |
+
|
64 |
+
# Flask stuff:
|
65 |
+
instance/
|
66 |
+
.webassets-cache
|
67 |
+
|
68 |
+
# Scrapy stuff:
|
69 |
+
.scrapy
|
70 |
+
|
71 |
+
# Sphinx documentation
|
72 |
+
docs/_build/
|
73 |
+
|
74 |
+
# PyBuilder
|
75 |
+
.pybuilder/
|
76 |
+
target/
|
77 |
+
|
78 |
+
# Jupyter Notebook
|
79 |
+
.ipynb_checkpoints
|
80 |
+
|
81 |
+
# IPython
|
82 |
+
profile_default/
|
83 |
+
ipython_config.py
|
84 |
+
|
85 |
+
# pyenv
|
86 |
+
# For a library or package, you might want to ignore these files since the code is
|
87 |
+
# intended to run in multiple environments; otherwise, check them in:
|
88 |
+
# .python-version
|
89 |
+
|
90 |
+
# pipenv
|
91 |
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
92 |
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
93 |
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
94 |
+
# install all needed dependencies.
|
95 |
+
#Pipfile.lock
|
96 |
+
|
97 |
+
# UV
|
98 |
+
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
99 |
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
100 |
+
# commonly ignored for libraries.
|
101 |
+
#uv.lock
|
102 |
+
|
103 |
+
# poetry
|
104 |
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
105 |
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
106 |
+
# commonly ignored for libraries.
|
107 |
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
108 |
+
#poetry.lock
|
109 |
+
|
110 |
+
# pdm
|
111 |
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
112 |
+
#pdm.lock
|
113 |
+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
114 |
+
# in version control.
|
115 |
+
# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
|
116 |
+
.pdm.toml
|
117 |
+
.pdm-python
|
118 |
+
.pdm-build/
|
119 |
+
|
120 |
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
121 |
+
__pypackages__/
|
122 |
+
|
123 |
+
# Celery stuff
|
124 |
+
celerybeat-schedule
|
125 |
+
celerybeat.pid
|
126 |
+
|
127 |
+
# SageMath parsed files
|
128 |
+
*.sage.py
|
129 |
+
|
130 |
+
# Environments
|
131 |
+
.env
|
132 |
+
.venv
|
133 |
+
env/
|
134 |
+
venv/
|
135 |
+
ENV/
|
136 |
+
env.bak/
|
137 |
+
venv.bak/
|
138 |
+
|
139 |
+
# Spyder project settings
|
140 |
+
.spyderproject
|
141 |
+
.spyproject
|
142 |
+
|
143 |
+
# Rope project settings
|
144 |
+
.ropeproject
|
145 |
+
|
146 |
+
# mkdocs documentation
|
147 |
+
/site
|
148 |
+
|
149 |
+
# mypy
|
150 |
+
.mypy_cache/
|
151 |
+
.dmypy.json
|
152 |
+
dmypy.json
|
153 |
+
|
154 |
+
# Pyre type checker
|
155 |
+
.pyre/
|
156 |
+
|
157 |
+
# pytype static type analyzer
|
158 |
+
.pytype/
|
159 |
+
|
160 |
+
# Cython debug symbols
|
161 |
+
cython_debug/
|
162 |
+
|
163 |
+
# PyCharm
|
164 |
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
165 |
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
166 |
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
167 |
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
168 |
+
#.idea/
|
169 |
+
|
170 |
+
|
171 |
+
# Boilerplate specific ignores
|
172 |
+
.gradio/
|
173 |
+
.ruff_cache/
|
.gitlint
ADDED
@@ -0,0 +1,143 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Edit this file as you like.
|
2 |
+
#
|
3 |
+
# All these sections are optional. Each section with the exception of [general] represents
|
4 |
+
# one rule and each key in it is an option for that specific rule.
|
5 |
+
#
|
6 |
+
# Rules and sections can be referenced by their full name or by id. For example
|
7 |
+
# section "[body-max-line-length]" could also be written as "[B1]". Full section names are
|
8 |
+
# used in here for clarity.
|
9 |
+
#
|
10 |
+
# [general]
|
11 |
+
# Ignore certain rules, this example uses both full name and id
|
12 |
+
# ignore=title-trailing-punctuation, T3
|
13 |
+
|
14 |
+
[general]
|
15 |
+
# You HAVE to add the rule here to enable it, only configuring (such as below)
|
16 |
+
# does NOT enable it.
|
17 |
+
contrib=contrib-title-conventional-commits
|
18 |
+
|
19 |
+
[contrib-title-conventional-commits]
|
20 |
+
# Specify allowed commit types. For details see: https://www.conventionalcommits.org/
|
21 |
+
types = build,chore,ci,docs,feat,fix,perf,refactor,revert,style,test
|
22 |
+
|
23 |
+
# verbosity should be a value between 1 and 3, the commandline -v flags take precedence over this
|
24 |
+
# verbosity = 2
|
25 |
+
|
26 |
+
# By default gitlint will ignore merge, revert, fixup and squash commits.
|
27 |
+
# ignore-merge-commits=true
|
28 |
+
# ignore-revert-commits=true
|
29 |
+
# ignore-fixup-commits=true
|
30 |
+
# ignore-squash-commits=true
|
31 |
+
|
32 |
+
# Ignore any data send to gitlint via stdin
|
33 |
+
# ignore-stdin=true
|
34 |
+
|
35 |
+
# Fetch additional meta-data from the local repository when manually passing a
|
36 |
+
# commit message to gitlint via stdin or --commit-msg. Disabled by default.
|
37 |
+
# staged=true
|
38 |
+
|
39 |
+
# Hard fail when the target commit range is empty. Note that gitlint will
|
40 |
+
# already fail by default on invalid commit ranges. This option is specifically
|
41 |
+
# to tell gitlint to fail on *valid but empty* commit ranges.
|
42 |
+
# Disabled by default.
|
43 |
+
# fail-without-commits=true
|
44 |
+
|
45 |
+
# Enable debug mode (prints more output). Disabled by default.
|
46 |
+
# debug=true
|
47 |
+
|
48 |
+
# Enable community contributed rules
|
49 |
+
# See http://jorisroovers.github.io/gitlint/contrib_rules for details
|
50 |
+
# contrib=contrib-title-conventional-commits,CC1
|
51 |
+
|
52 |
+
# Set the extra-path where gitlint will search for user defined rules
|
53 |
+
# See http://jorisroovers.github.io/gitlint/user_defined_rules for details
|
54 |
+
# extra-path=examples/
|
55 |
+
|
56 |
+
# This is an example of how to configure the "title-max-length" rule and
|
57 |
+
# set the line-length it enforces to 50
|
58 |
+
# [title-max-length]
|
59 |
+
# line-length=50
|
60 |
+
|
61 |
+
# Conversely, you can also enforce minimal length of a title with the
|
62 |
+
# "title-min-length" rule:
|
63 |
+
# [title-min-length]
|
64 |
+
# min-length=5
|
65 |
+
|
66 |
+
# [title-must-not-contain-word]
|
67 |
+
# Comma-separated list of words that should not occur in the title. Matching is case
|
68 |
+
# insensitive. It's fine if the keyword occurs as part of a larger word (so "WIPING"
|
69 |
+
# will not cause a violation, but "WIP: my title" will.
|
70 |
+
# words=wip
|
71 |
+
|
72 |
+
# [title-match-regex]
|
73 |
+
# python-style regex that the commit-msg title must match
|
74 |
+
# Note that the regex can contradict with other rules if not used correctly
|
75 |
+
# (e.g. title-must-not-contain-word).
|
76 |
+
# regex=^US[0-9]*
|
77 |
+
|
78 |
+
# [body-max-line-length]
|
79 |
+
# line-length=72
|
80 |
+
|
81 |
+
# [body-min-length]
|
82 |
+
# min-length=5
|
83 |
+
|
84 |
+
# [body-is-missing]
|
85 |
+
# Whether to ignore this rule on merge commits (which typically only have a title)
|
86 |
+
# default = True
|
87 |
+
# ignore-merge-commits=false
|
88 |
+
|
89 |
+
# [body-changed-file-mention]
|
90 |
+
# List of files that need to be explicitly mentioned in the body when they are changed
|
91 |
+
# This is useful for when developers often erroneously edit certain files or git submodules.
|
92 |
+
# By specifying this rule, developers can only change the file when they explicitly reference
|
93 |
+
# it in the commit message.
|
94 |
+
# files=gitlint-core/gitlint/rules.py,README.md
|
95 |
+
|
96 |
+
# [body-match-regex]
|
97 |
+
# python-style regex that the commit-msg body must match.
|
98 |
+
# E.g. body must end in My-Commit-Tag: foo
|
99 |
+
# regex=My-Commit-Tag: foo$
|
100 |
+
|
101 |
+
# [author-valid-email]
|
102 |
+
# python-style regex that the commit author email address must match.
|
103 |
+
# For example, use the following regex if you only want to allow email addresses from foo.com
|
104 |
+
# regex=[^@][email protected]
|
105 |
+
|
106 |
+
# [ignore-by-title]
|
107 |
+
# Ignore certain rules for commits of which the title matches a regex
|
108 |
+
# E.g. Match commit titles that start with "Release"
|
109 |
+
# regex=^Release(.*)
|
110 |
+
|
111 |
+
# Ignore certain rules, you can reference them by their id or by their full name
|
112 |
+
# Use 'all' to ignore all rules
|
113 |
+
# ignore=T1,body-min-length
|
114 |
+
|
115 |
+
# [ignore-by-body]
|
116 |
+
# Ignore certain rules for commits of which the body has a line that matches a regex
|
117 |
+
# E.g. Match bodies that have a line that that contain "release"
|
118 |
+
# regex=(.*)release(.*)
|
119 |
+
#
|
120 |
+
# Ignore certain rules, you can reference them by their id or by their full name
|
121 |
+
# Use 'all' to ignore all rules
|
122 |
+
# ignore=T1,body-min-length
|
123 |
+
|
124 |
+
# [ignore-body-lines]
|
125 |
+
# Ignore certain lines in a commit body that match a regex.
|
126 |
+
# E.g. Ignore all lines that start with 'Co-Authored-By'
|
127 |
+
# regex=^Co-Authored-By
|
128 |
+
|
129 |
+
# [ignore-by-author-name]
|
130 |
+
# Ignore certain rules for commits of which the author name matches a regex
|
131 |
+
# E.g. Match commits made by dependabot
|
132 |
+
# regex=(.*)dependabot(.*)
|
133 |
+
#
|
134 |
+
# Ignore certain rules, you can reference them by their id or by their full name
|
135 |
+
# Use 'all' to ignore all rules
|
136 |
+
# ignore=T1,body-min-length
|
137 |
+
|
138 |
+
# This is a contrib rule - a community contributed rule. These are disabled by default.
|
139 |
+
# You need to explicitly enable them one-by-one by adding them to the "contrib" option
|
140 |
+
# under [general] section above.
|
141 |
+
# [contrib-title-conventional-commits]
|
142 |
+
# Specify allowed commit types. For details see: https://www.conventionalcommits.org/
|
143 |
+
# types = bugfix,user-story,epic
|
.pre-commit-config.yaml
ADDED
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
repos:
|
2 |
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
3 |
+
rev: v5.0.0
|
4 |
+
hooks:
|
5 |
+
- id: check-added-large-files
|
6 |
+
- id: check-ast
|
7 |
+
- id: check-case-conflict
|
8 |
+
- id: check-json
|
9 |
+
- id: check-merge-conflict
|
10 |
+
- id: check-toml
|
11 |
+
- id: end-of-file-fixer
|
12 |
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
13 |
+
# Ruff version.
|
14 |
+
rev: v0.8.6
|
15 |
+
hooks:
|
16 |
+
- id: ruff
|
17 |
+
- repo: https://github.com/pycqa/isort
|
18 |
+
rev: 5.13.2
|
19 |
+
hooks:
|
20 |
+
- id: isort
|
21 |
+
args: ["--profile", "black"]
|
22 |
+
- repo: https://github.com/asottile/pyupgrade
|
23 |
+
rev: v3.19.1
|
24 |
+
hooks:
|
25 |
+
- id: pyupgrade
|
26 |
+
args: ["--py310-plus"]
|
27 |
+
- repo: https://github.com/psf/black
|
28 |
+
rev: 24.10.0
|
29 |
+
hooks:
|
30 |
+
- id: black
|
31 |
+
args:
|
32 |
+
- --line-length=120
|
33 |
+
- repo: https://github.com/jorisroovers/gitlint
|
34 |
+
rev: v0.19.1
|
35 |
+
hooks:
|
36 |
+
- id: gitlint
|
37 |
+
name: gitlint
|
38 |
+
language: python
|
39 |
+
entry: gitlint
|
40 |
+
args: [--staged, --msg-filename]
|
41 |
+
stages: [commit-msg]
|
42 |
+
- repo: https://github.com/python-poetry/poetry
|
43 |
+
rev: '1.8.0'
|
44 |
+
hooks:
|
45 |
+
- id: poetry-check
|
46 |
+
- id: poetry-lock
|
47 |
+
args: [--no-update]
|
48 |
+
language_version: "3.10"
|
49 |
+
- id: poetry-export
|
50 |
+
name: poetry export for base requirements
|
51 |
+
args: [-f, requirements.txt, -o, requirements.txt, -n, --only=main, --without-hashes]
|
poetry.lock
ADDED
The diff for this file is too large to render.
See raw diff
|
|
pyproject.toml
ADDED
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[tool.poetry]
|
2 |
+
name = "granite-3.1-8b-instruct"
|
3 |
+
version = "0.1.0"
|
4 |
+
description = "A demo of the IBM Granite 3.1 8b instruct model"
|
5 |
+
authors = [
|
6 |
+
"James Sutton <[email protected]>",
|
7 |
+
"Graham White <[email protected]>",
|
8 |
+
"Michael Desmond <[email protected]>",
|
9 |
+
]
|
10 |
+
license = "Apache-2.0"
|
11 |
+
readme = "README.md"
|
12 |
+
package-mode = false
|
13 |
+
|
14 |
+
[tool.poetry.dependencies]
|
15 |
+
python = ">=3.10,<3.11"
|
16 |
+
gradio = "5.12.0"
|
17 |
+
torch = "2.4.0"
|
18 |
+
spaces = "0.30.4"
|
19 |
+
transformers = "^4.47.1"
|
20 |
+
accelerate = "^1.2.1"
|
21 |
+
|
22 |
+
|
23 |
+
[tool.poetry.group.dev.dependencies]
|
24 |
+
pre-commit = "^4.0.1"
|
25 |
+
git-lint = "^0.1.2"
|
26 |
+
ruff = "^0.8.3"
|
27 |
+
pytest = "^8.3.4"
|
28 |
+
|
29 |
+
|
30 |
+
[build-system]
|
31 |
+
requires = ["poetry-core"]
|
32 |
+
build-backend = "poetry.core.masonry.api"
|
33 |
+
|
34 |
+
|
35 |
+
[tool.ruff]
|
36 |
+
select = [
|
37 |
+
"E", # pycodestyle
|
38 |
+
"F", # pyflakes
|
39 |
+
"UP", # pyupgrade
|
40 |
+
"D", # pydocstyle
|
41 |
+
"I", # isort
|
42 |
+
"B", # bugbear
|
43 |
+
"ANN", # annotations
|
44 |
+
"N", # pep8-naming
|
45 |
+
"C4", # Comprehensions
|
46 |
+
"DTZ", # DatetimeZ
|
47 |
+
"Q", # Quotes
|
48 |
+
"SIM", # Simplify
|
49 |
+
"RUF", # Ruff
|
50 |
+
]
|
51 |
+
ignore = ["D203", "D213"]
|
52 |
+
fixable = ["ALL"]
|
53 |
+
unfixable = []
|
54 |
+
line-length = 120
|
55 |
+
|
56 |
+
|
57 |
+
[tool.black]
|
58 |
+
line-length = 120
|
59 |
+
|
60 |
+
[tool.ruff.lint.pydocstyle]
|
61 |
+
convention = "google"
|
requirements.txt
ADDED
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
accelerate==1.2.1 ; python_version >= "3.10" and python_version < "3.11"
|
2 |
+
aiofiles==23.2.1 ; python_version >= "3.10" and python_version < "3.11"
|
3 |
+
annotated-types==0.7.0 ; python_version >= "3.10" and python_version < "3.11"
|
4 |
+
anyio==4.8.0 ; python_version >= "3.10" and python_version < "3.11"
|
5 |
+
certifi==2024.12.14 ; python_version >= "3.10" and python_version < "3.11"
|
6 |
+
charset-normalizer==3.4.1 ; python_version >= "3.10" and python_version < "3.11"
|
7 |
+
click==8.1.8 ; python_version >= "3.10" and python_version < "3.11" and sys_platform != "emscripten"
|
8 |
+
colorama==0.4.6 ; python_version >= "3.10" and python_version < "3.11" and platform_system == "Windows"
|
9 |
+
exceptiongroup==1.2.2 ; python_version >= "3.10" and python_version < "3.11"
|
10 |
+
fastapi==0.115.6 ; python_version >= "3.10" and python_version < "3.11"
|
11 |
+
ffmpy==0.5.0 ; python_version >= "3.10" and python_version < "3.11"
|
12 |
+
filelock==3.16.1 ; python_version >= "3.10" and python_version < "3.11"
|
13 |
+
fsspec==2024.12.0 ; python_version >= "3.10" and python_version < "3.11"
|
14 |
+
gradio-client==1.5.4 ; python_version >= "3.10" and python_version < "3.11"
|
15 |
+
gradio==5.12.0 ; python_version >= "3.10" and python_version < "3.11"
|
16 |
+
h11==0.14.0 ; python_version >= "3.10" and python_version < "3.11"
|
17 |
+
httpcore==1.0.7 ; python_version >= "3.10" and python_version < "3.11"
|
18 |
+
httpx==0.28.1 ; python_version >= "3.10" and python_version < "3.11"
|
19 |
+
huggingface-hub==0.27.1 ; python_version >= "3.10" and python_version < "3.11"
|
20 |
+
idna==3.10 ; python_version >= "3.10" and python_version < "3.11"
|
21 |
+
jinja2==3.1.5 ; python_version >= "3.10" and python_version < "3.11"
|
22 |
+
markdown-it-py==3.0.0 ; python_version >= "3.10" and python_version < "3.11" and sys_platform != "emscripten"
|
23 |
+
markupsafe==2.1.5 ; python_version >= "3.10" and python_version < "3.11"
|
24 |
+
mdurl==0.1.2 ; python_version >= "3.10" and python_version < "3.11" and sys_platform != "emscripten"
|
25 |
+
mpmath==1.3.0 ; python_version >= "3.10" and python_version < "3.11"
|
26 |
+
networkx==3.4.2 ; python_version >= "3.10" and python_version < "3.11"
|
27 |
+
numpy==2.2.1 ; python_version >= "3.10" and python_version < "3.11"
|
28 |
+
nvidia-cublas-cu12==12.1.3.1 ; platform_system == "Linux" and platform_machine == "x86_64" and python_version >= "3.10" and python_version < "3.11"
|
29 |
+
nvidia-cuda-cupti-cu12==12.1.105 ; platform_system == "Linux" and platform_machine == "x86_64" and python_version >= "3.10" and python_version < "3.11"
|
30 |
+
nvidia-cuda-nvrtc-cu12==12.1.105 ; platform_system == "Linux" and platform_machine == "x86_64" and python_version >= "3.10" and python_version < "3.11"
|
31 |
+
nvidia-cuda-runtime-cu12==12.1.105 ; platform_system == "Linux" and platform_machine == "x86_64" and python_version >= "3.10" and python_version < "3.11"
|
32 |
+
nvidia-cudnn-cu12==9.1.0.70 ; platform_system == "Linux" and platform_machine == "x86_64" and python_version >= "3.10" and python_version < "3.11"
|
33 |
+
nvidia-cufft-cu12==11.0.2.54 ; platform_system == "Linux" and platform_machine == "x86_64" and python_version >= "3.10" and python_version < "3.11"
|
34 |
+
nvidia-curand-cu12==10.3.2.106 ; platform_system == "Linux" and platform_machine == "x86_64" and python_version >= "3.10" and python_version < "3.11"
|
35 |
+
nvidia-cusolver-cu12==11.4.5.107 ; platform_system == "Linux" and platform_machine == "x86_64" and python_version >= "3.10" and python_version < "3.11"
|
36 |
+
nvidia-cusparse-cu12==12.1.0.106 ; platform_system == "Linux" and platform_machine == "x86_64" and python_version >= "3.10" and python_version < "3.11"
|
37 |
+
nvidia-nccl-cu12==2.20.5 ; platform_system == "Linux" and platform_machine == "x86_64" and python_version >= "3.10" and python_version < "3.11"
|
38 |
+
nvidia-nvjitlink-cu12==12.6.85 ; platform_system == "Linux" and platform_machine == "x86_64" and python_version >= "3.10" and python_version < "3.11"
|
39 |
+
nvidia-nvtx-cu12==12.1.105 ; platform_system == "Linux" and platform_machine == "x86_64" and python_version >= "3.10" and python_version < "3.11"
|
40 |
+
orjson==3.10.14 ; python_version >= "3.10" and python_version < "3.11"
|
41 |
+
packaging==24.2 ; python_version >= "3.10" and python_version < "3.11"
|
42 |
+
pandas==2.2.3 ; python_version >= "3.10" and python_version < "3.11"
|
43 |
+
pillow==11.1.0 ; python_version >= "3.10" and python_version < "3.11"
|
44 |
+
psutil==5.9.8 ; python_version >= "3.10" and python_version < "3.11"
|
45 |
+
pydantic-core==2.27.2 ; python_version >= "3.10" and python_version < "3.11"
|
46 |
+
pydantic==2.10.5 ; python_version >= "3.10" and python_version < "3.11"
|
47 |
+
pydub==0.25.1 ; python_version >= "3.10" and python_version < "3.11"
|
48 |
+
pygments==2.19.1 ; python_version >= "3.10" and python_version < "3.11" and sys_platform != "emscripten"
|
49 |
+
python-dateutil==2.9.0.post0 ; python_version >= "3.10" and python_version < "3.11"
|
50 |
+
python-multipart==0.0.20 ; python_version >= "3.10" and python_version < "3.11"
|
51 |
+
pytz==2024.2 ; python_version >= "3.10" and python_version < "3.11"
|
52 |
+
pyyaml==6.0.2 ; python_version >= "3.10" and python_version < "3.11"
|
53 |
+
regex==2024.11.6 ; python_version >= "3.10" and python_version < "3.11"
|
54 |
+
requests==2.32.3 ; python_version >= "3.10" and python_version < "3.11"
|
55 |
+
rich==13.9.4 ; python_version >= "3.10" and python_version < "3.11" and sys_platform != "emscripten"
|
56 |
+
ruff==0.8.6 ; python_version >= "3.10" and python_version < "3.11" and sys_platform != "emscripten"
|
57 |
+
safehttpx==0.1.6 ; python_version >= "3.10" and python_version < "3.11"
|
58 |
+
safetensors==0.5.2 ; python_version >= "3.10" and python_version < "3.11"
|
59 |
+
semantic-version==2.10.0 ; python_version >= "3.10" and python_version < "3.11"
|
60 |
+
shellingham==1.5.4 ; python_version >= "3.10" and python_version < "3.11" and sys_platform != "emscripten"
|
61 |
+
six==1.17.0 ; python_version >= "3.10" and python_version < "3.11"
|
62 |
+
sniffio==1.3.1 ; python_version >= "3.10" and python_version < "3.11"
|
63 |
+
spaces==0.30.4 ; python_version >= "3.10" and python_version < "3.11"
|
64 |
+
starlette==0.41.3 ; python_version >= "3.10" and python_version < "3.11"
|
65 |
+
sympy==1.13.3 ; python_version >= "3.10" and python_version < "3.11"
|
66 |
+
tokenizers==0.21.0 ; python_version >= "3.10" and python_version < "3.11"
|
67 |
+
tomlkit==0.13.2 ; python_version >= "3.10" and python_version < "3.11"
|
68 |
+
torch==2.4.0 ; python_version >= "3.10" and python_version < "3.11"
|
69 |
+
tqdm==4.67.1 ; python_version >= "3.10" and python_version < "3.11"
|
70 |
+
transformers==4.48.0 ; python_version >= "3.10" and python_version < "3.11"
|
71 |
+
triton==3.0.0 ; platform_system == "Linux" and platform_machine == "x86_64" and python_version < "3.11" and python_version >= "3.10"
|
72 |
+
typer==0.15.1 ; python_version >= "3.10" and python_version < "3.11" and sys_platform != "emscripten"
|
73 |
+
typing-extensions==4.12.2 ; python_version >= "3.10" and python_version < "3.11"
|
74 |
+
tzdata==2024.2 ; python_version >= "3.10" and python_version < "3.11"
|
75 |
+
urllib3==2.3.0 ; python_version >= "3.10" and python_version < "3.11"
|
76 |
+
uvicorn==0.34.0 ; python_version >= "3.10" and python_version < "3.11" and sys_platform != "emscripten"
|
77 |
+
websockets==14.1 ; python_version >= "3.10" and python_version < "3.11"
|
src/app.css
ADDED
@@ -0,0 +1,75 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* Hide the standard Gradio footer */
|
2 |
+
footer {
|
3 |
+
display: none !important;
|
4 |
+
}
|
5 |
+
/* Make the text in the input box and chat label bigger */
|
6 |
+
textarea, .wrapper > label {
|
7 |
+
font-size: var(--text-md)
|
8 |
+
}
|
9 |
+
.input-container {
|
10 |
+
align-items: center;
|
11 |
+
}
|
12 |
+
/* Make the chat label bold */
|
13 |
+
.wrapper > label {
|
14 |
+
font-weight: 600;
|
15 |
+
}
|
16 |
+
/* Limit the overall width of the demo */
|
17 |
+
.gradio-container {
|
18 |
+
max-width: 1024px !important;
|
19 |
+
margin: 5vh auto !important;
|
20 |
+
}
|
21 |
+
/* Theme anchor links with Carbon coloring */
|
22 |
+
.gr_docs_link a, .gr_docs_link a > i {
|
23 |
+
color: #78A9FF;
|
24 |
+
text-decoration: none;
|
25 |
+
}
|
26 |
+
/* Title alignment with the Granite icon */
|
27 |
+
.gr_title {
|
28 |
+
display: flex;
|
29 |
+
align-items: center;
|
30 |
+
margin-bottom: -0.5rem;
|
31 |
+
}
|
32 |
+
.gr_title img {
|
33 |
+
height: 42px;
|
34 |
+
width: 42px;
|
35 |
+
margin-right: 1rem;
|
36 |
+
filter: invert(0%) sepia(0%) saturate(7459%) hue-rotate(154deg) brightness(96%) contrast(100%);
|
37 |
+
}
|
38 |
+
.gr_title h1 {
|
39 |
+
margin: auto !important;
|
40 |
+
font-size: 36px;
|
41 |
+
font-weight: 600;
|
42 |
+
}
|
43 |
+
/* Only one form on the page, within the Accordion component */
|
44 |
+
.form {
|
45 |
+
flex-direction: row;
|
46 |
+
background-color: var(--block-background-fill);
|
47 |
+
}
|
48 |
+
.gr_accordion_element {
|
49 |
+
width: 50%;
|
50 |
+
margin: 0px;
|
51 |
+
}
|
52 |
+
/* Color the example background */
|
53 |
+
.example:hover {
|
54 |
+
background-color: #D0E2FF
|
55 |
+
}
|
56 |
+
/* Centre the example text within the example box */
|
57 |
+
.example-text-content {
|
58 |
+
margin-top: auto;
|
59 |
+
margin-bottom: auto;
|
60 |
+
}
|
61 |
+
/* Centre the values in advanced settings */
|
62 |
+
.tab-like-container {
|
63 |
+
align-items: center;
|
64 |
+
}
|
65 |
+
/* dark mode */
|
66 |
+
@media (prefers-color-scheme: dark) {
|
67 |
+
/* Color the Granite icon in white */
|
68 |
+
.gr_title img {
|
69 |
+
filter: invert(100%) sepia(100%) saturate(0%) hue-rotate(162deg) brightness(101%) contrast(104%);
|
70 |
+
}
|
71 |
+
/* Color the example background */
|
72 |
+
.example:hover {
|
73 |
+
background-color: #4589FF
|
74 |
+
}
|
75 |
+
}
|
src/app.py
ADDED
@@ -0,0 +1,392 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from collections.abc import Iterator
|
2 |
+
from datetime import datetime
|
3 |
+
from pathlib import Path
|
4 |
+
from threading import Thread
|
5 |
+
|
6 |
+
import gradio as gr
|
7 |
+
import spaces
|
8 |
+
import torch
|
9 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer
|
10 |
+
|
11 |
+
# Vision model imports
|
12 |
+
from transformers import LlavaNextProcessor, LlavaNextForConditionalGeneration
|
13 |
+
import random
|
14 |
+
|
15 |
+
from themes.research_monochrome import theme
|
16 |
+
|
17 |
+
today_date = datetime.today().strftime("%B %-d, %Y") # noqa: DTZ002
|
18 |
+
|
19 |
+
SYS_PROMPT = f"""Knowledge Cutoff Date: April 2024.
|
20 |
+
Today's Date: {today_date}.
|
21 |
+
You are Granite, developed by IBM. You are a helpful AI assistant"""
|
22 |
+
TITLE = "IBM Granite 3.1 8b Instruct & Vision Preview"
|
23 |
+
DESCRIPTION = """
|
24 |
+
<p>Granite 3.1 8b instruct is an open-source LLM supporting a 128k context window and Granite Vision 3.1 2B Preview for vision-language capabilities. Start with one of the sample prompts
|
25 |
+
or enter your own. Upload an image to use the vision model. Keep in mind that AI can occasionally make mistakes.
|
26 |
+
<span class="gr_docs_link">
|
27 |
+
<a href="https://www.ibm.com/granite/docs/">View Granite Instruct Documentation <i class="fa fa-external-link"></i></a>
|
28 |
+
</span>
|
29 |
+
<span class="gr_docs_link">
|
30 |
+
<a href="https://www.ibm.com/granite/vision/docs/">View Granite Vision Documentation <i class="fa fa-external-link"></i></a>
|
31 |
+
</span>
|
32 |
+
</p>
|
33 |
+
"""
|
34 |
+
MAX_INPUT_TOKEN_LENGTH = 128_000
|
35 |
+
MAX_NEW_TOKENS = 1024
|
36 |
+
TEMPERATURE = 0.7
|
37 |
+
TOP_P = 0.85
|
38 |
+
TOP_K = 50
|
39 |
+
REPETITION_PENALTY = 1.05
|
40 |
+
|
41 |
+
VISION_TEMPERATURE = 0.2
|
42 |
+
VISION_TOP_P = 0.95
|
43 |
+
VISION_TOP_K = 50
|
44 |
+
VISION_MAX_TOKENS = 128
|
45 |
+
|
46 |
+
|
47 |
+
if not torch.cuda.is_available():
|
48 |
+
print("This demo may not work on CPU.")
|
49 |
+
|
50 |
+
# Text model loading
|
51 |
+
text_model = AutoModelForCausalLM.from_pretrained(
|
52 |
+
"ibm-granite/granite-3.1-8b-instruct", torch_dtype=torch.float16, device_map="auto"
|
53 |
+
)
|
54 |
+
text_tokenizer = AutoTokenizer.from_pretrained("ibm-granite/granite-3.1-8b-instruct")
|
55 |
+
text_tokenizer.use_default_system_prompt = False
|
56 |
+
|
57 |
+
# Vision model loading
|
58 |
+
vision_model_path = "ibm-granite/granite-vision-3.1-2b-preview"
|
59 |
+
vision_processor = LlavaNextProcessor.from_pretrained(vision_model_path, use_fast=True)
|
60 |
+
vision_model = LlavaNextForConditionalGeneration.from_pretrained(vision_model_path, torch_dtype="auto", device_map="auto")
|
61 |
+
|
62 |
+
|
63 |
+
@spaces.GPU
|
64 |
+
def generate(
|
65 |
+
message: str,
|
66 |
+
chat_history: list[dict],
|
67 |
+
temperature: float = TEMPERATURE,
|
68 |
+
repetition_penalty: float = REPETITION_PENALTY,
|
69 |
+
top_p: float = TOP_P,
|
70 |
+
top_k: float = TOP_K,
|
71 |
+
max_new_tokens: int = MAX_NEW_TOKENS,
|
72 |
+
) -> Iterator[str]:
|
73 |
+
"""Generate function for text chat demo."""
|
74 |
+
# Build messages
|
75 |
+
conversation = []
|
76 |
+
conversation.append({"role": "system", "content": SYS_PROMPT})
|
77 |
+
conversation += chat_history
|
78 |
+
conversation.append({"role": "user", "content": message})
|
79 |
+
|
80 |
+
# Convert messages to prompt format
|
81 |
+
input_ids = text_tokenizer.apply_chat_template(
|
82 |
+
conversation,
|
83 |
+
return_tensors="pt",
|
84 |
+
add_generation_prompt=True,
|
85 |
+
truncation=True,
|
86 |
+
max_length=MAX_INPUT_TOKEN_LENGTH - max_new_tokens,
|
87 |
+
)
|
88 |
+
|
89 |
+
input_ids = input_ids.to(text_model.device)
|
90 |
+
streamer = TextIteratorStreamer(text_tokenizer, skip_prompt=True, skip_special_tokens=True)
|
91 |
+
generate_kwargs = dict(
|
92 |
+
{"input_ids": input_ids},
|
93 |
+
streamer=streamer,
|
94 |
+
max_new_tokens=max_new_tokens,
|
95 |
+
do_sample=True,
|
96 |
+
top_p=top_p,
|
97 |
+
top_k=top_k,
|
98 |
+
temperature=temperature,
|
99 |
+
num_beams=1,
|
100 |
+
repetition_penalty=repetition_penalty,
|
101 |
+
)
|
102 |
+
|
103 |
+
t = Thread(target=text_model.generate, kwargs=generate_kwargs)
|
104 |
+
t.start()
|
105 |
+
|
106 |
+
outputs = []
|
107 |
+
for text in streamer:
|
108 |
+
outputs.append(text)
|
109 |
+
yield "".join(outputs)
|
110 |
+
|
111 |
+
|
112 |
+
def get_text_from_content(content):
|
113 |
+
texts = []
|
114 |
+
for item in content:
|
115 |
+
if item["type"] == "text":
|
116 |
+
texts.append(item["text"])
|
117 |
+
elif item["type"] == "image":
|
118 |
+
texts.append("[Image]")
|
119 |
+
return " ".join(texts)
|
120 |
+
|
121 |
+
@spaces.GPU
|
122 |
+
def chat_inference(image, text, conversation, temperature=VISION_TEMPERATURE, top_p=VISION_TOP_P, top_k=VISION_TOP_K, max_tokens=VISION_MAX_TOKENS):
|
123 |
+
if conversation is None:
|
124 |
+
conversation = []
|
125 |
+
|
126 |
+
user_content = []
|
127 |
+
if image is not None:
|
128 |
+
user_content.append({"type": "image", "image": image})
|
129 |
+
if text and text.strip():
|
130 |
+
user_content.append({"type": "text", "text": text.strip()})
|
131 |
+
if not user_content:
|
132 |
+
return conversation_display(conversation), conversation
|
133 |
+
|
134 |
+
conversation.append({
|
135 |
+
"role": "user",
|
136 |
+
"content": user_content
|
137 |
+
})
|
138 |
+
|
139 |
+
inputs = vision_processor.apply_chat_template(
|
140 |
+
conversation,
|
141 |
+
add_generation_prompt=True,
|
142 |
+
tokenize=True,
|
143 |
+
return_dict=True,
|
144 |
+
return_tensors="pt"
|
145 |
+
).to("cuda")
|
146 |
+
|
147 |
+
torch.manual_seed(random.randint(0, 10000))
|
148 |
+
|
149 |
+
generation_kwargs = {
|
150 |
+
"max_new_tokens": max_tokens,
|
151 |
+
"temperature": temperature,
|
152 |
+
"top_p": top_p,
|
153 |
+
"top_k": top_k,
|
154 |
+
"do_sample": True,
|
155 |
+
}
|
156 |
+
|
157 |
+
output = vision_model.generate(**inputs, **generation_kwargs)
|
158 |
+
assistant_response = vision_processor.decode(output[0], skip_special_tokens=True)
|
159 |
+
|
160 |
+
conversation.append({
|
161 |
+
"role": "assistant",
|
162 |
+
"content": [{"type": "text", "text": assistant_response.strip()}]
|
163 |
+
})
|
164 |
+
|
165 |
+
return conversation_display(conversation), conversation
|
166 |
+
|
167 |
+
def conversation_display(conversation):
|
168 |
+
chat_history = []
|
169 |
+
for msg in conversation:
|
170 |
+
if msg["role"] == "user":
|
171 |
+
user_text = get_text_from_content(msg["content"])
|
172 |
+
chat_history.append({"role": "user", "content": user_text})
|
173 |
+
elif msg["role"] == "assistant":
|
174 |
+
assistant_text = msg["content"][0]["text"].split("<|assistant|>")[-1].strip()
|
175 |
+
chat_history.append({"role": "assistant", "content": assistant_text})
|
176 |
+
return chat_history
|
177 |
+
|
178 |
+
def clear_chat():
|
179 |
+
return [], [], "", None, [] # Cleared state for both text and vision
|
180 |
+
|
181 |
+
css_file_path = Path(Path(__file__).parent / "app.css")
|
182 |
+
head_file_path = Path(Path(__file__).parent / "app_head.html")
|
183 |
+
|
184 |
+
# Advanced settings (displayed in Accordion) - Text Model
|
185 |
+
text_temperature_slider = gr.Slider(
|
186 |
+
minimum=0, maximum=1.0, value=TEMPERATURE, step=0.1, label="Text Temperature", elem_classes=["gr_accordion_element"]
|
187 |
+
)
|
188 |
+
text_top_p_slider = gr.Slider(
|
189 |
+
minimum=0, maximum=1.0, value=TOP_P, step=0.05, label="Text Top P", elem_classes=["gr_accordion_element"]
|
190 |
+
)
|
191 |
+
text_top_k_slider = gr.Slider(
|
192 |
+
minimum=0, maximum=100, value=TOP_K, step=1, label="Text Top K", elem_classes=["gr_accordion_element"]
|
193 |
+
)
|
194 |
+
text_repetition_penalty_slider = gr.Slider(
|
195 |
+
minimum=0,
|
196 |
+
maximum=2.0,
|
197 |
+
value=REPETITION_PENALTY,
|
198 |
+
step=0.05,
|
199 |
+
label="Text Repetition Penalty",
|
200 |
+
elem_classes=["gr_accordion_element"],
|
201 |
+
)
|
202 |
+
text_max_new_tokens_slider = gr.Slider(
|
203 |
+
minimum=1,
|
204 |
+
maximum=2000,
|
205 |
+
value=MAX_NEW_TOKENS,
|
206 |
+
step=1,
|
207 |
+
label="Text Max New Tokens",
|
208 |
+
elem_classes=["gr_accordion_element"],
|
209 |
+
)
|
210 |
+
text_chat_interface_accordion = gr.Accordion(label="Text Model Advanced Settings", open=False)
|
211 |
+
|
212 |
+
# Advanced settings (displayed in Accordion) - Vision Model
|
213 |
+
vision_temperature_slider = gr.Slider(
|
214 |
+
minimum=0.0, maximum=2.0, value=VISION_TEMPERATURE, step=0.01, label="Vision Temperature", elem_classes=["gr_accordion_element"]
|
215 |
+
)
|
216 |
+
vision_top_p_slider = gr.Slider(
|
217 |
+
minimum=0.0, maximum=1.0, value=VISION_TOP_P, step=0.01, label="Vision Top p", elem_classes=["gr_accordion_element"]
|
218 |
+
)
|
219 |
+
vision_top_k_slider = gr.Slider(
|
220 |
+
minimum=0, maximum=100, value=VISION_TOP_K, step=1, label="Vision Top k", elem_classes=["gr_accordion_element"]
|
221 |
+
)
|
222 |
+
vision_max_tokens_slider = gr.Slider(
|
223 |
+
minimum=10, maximum=300, value=VISION_MAX_TOKENS, step=1, label="Vision Max Tokens", elem_classes=["gr_accordion_element"]
|
224 |
+
)
|
225 |
+
vision_chat_interface_accordion = gr.Accordion(label="Vision Model Advanced Settings", open=False)
|
226 |
+
|
227 |
+
|
228 |
+
with gr.Blocks(fill_height=True, css_paths=css_file_path, head_paths=head_file_path, theme=theme, title=TITLE) as demo:
|
229 |
+
gr.HTML(f"<h1>{TITLE}</h1>", elem_classes=["gr_title"])
|
230 |
+
gr.HTML(DESCRIPTION)
|
231 |
+
|
232 |
+
chatbot = gr.Chatbot(label="Chat History", elem_id="chatbot", height=500, type='messages')
|
233 |
+
text_input = gr.Textbox(lines=2, placeholder="Enter your message here", label="Message")
|
234 |
+
image_input = gr.Image(type="pil", label="Upload Image (optional)")
|
235 |
+
|
236 |
+
with text_chat_interface_accordion:
|
237 |
+
text_temperature_slider
|
238 |
+
text_top_p_slider
|
239 |
+
text_top_k_slider
|
240 |
+
text_repetition_penalty_slider
|
241 |
+
text_max_new_tokens_slider
|
242 |
+
|
243 |
+
with vision_chat_interface_accordion:
|
244 |
+
vision_temperature_slider
|
245 |
+
vision_top_p_slider
|
246 |
+
vision_top_k_slider
|
247 |
+
vision_max_tokens_slider
|
248 |
+
|
249 |
+
|
250 |
+
clear_button = gr.Button("Clear Chat")
|
251 |
+
send_button = gr.Button("Send Message") # Changed from "Chat" to "Send Message" for clarity
|
252 |
+
|
253 |
+
text_state = gr.State([]) # State for text chatbot history
|
254 |
+
vision_state = gr.State([]) # State for vision chatbot history
|
255 |
+
chatbot_type_state = gr.State("text") # State to track which chatbot is in use
|
256 |
+
|
257 |
+
def send_message(image_input, text_input, chatbot_type_state, text_state, vision_state,
|
258 |
+
text_temperature, text_repetition_penalty, text_top_p, text_top_k, text_max_new_tokens,
|
259 |
+
vision_temperature, vision_top_p, vision_top_k, vision_max_tokens):
|
260 |
+
if image_input:
|
261 |
+
chatbot_type_state = "vision"
|
262 |
+
history = vision_state
|
263 |
+
gen_kwargs_vision = {
|
264 |
+
"temperature": vision_temperature,
|
265 |
+
"top_p": vision_top_p,
|
266 |
+
"top_k": vision_top_k,
|
267 |
+
"max_tokens": vision_max_tokens,
|
268 |
+
"conversation": history
|
269 |
+
}
|
270 |
+
chat_output, updated_vision_state = chat_inference(image=image_input, text=text_input, **gen_kwargs_vision)
|
271 |
+
return chat_output, updated_vision_state, chatbot_type_state, gr.ChatInterface.update(visible=False), gr.Chatbot.update(visible=True) # Hide text interface, show vision chatbot
|
272 |
+
|
273 |
+
else:
|
274 |
+
chatbot_type_state = "text"
|
275 |
+
history = text_state
|
276 |
+
gen_kwargs_text = {
|
277 |
+
"temperature": text_temperature,
|
278 |
+
"repetition_penalty": text_repetition_penalty,
|
279 |
+
"top_p": text_top_p,
|
280 |
+
"top_k": text_top_k,
|
281 |
+
"max_new_tokens": text_max_new_tokens,
|
282 |
+
"message": text_input,
|
283 |
+
"chat_history": history
|
284 |
+
}
|
285 |
+
|
286 |
+
chat_output_iterator = generate(**gen_kwargs_text)
|
287 |
+
output_text = ""
|
288 |
+
for text_chunk in chat_output_iterator:
|
289 |
+
output_text = text_chunk
|
290 |
+
|
291 |
+
updated_text_state = history + [{"role": "user", "content": text_input}, {"role": "assistant", "content": output_text}]
|
292 |
+
text_chatbot_history = updated_text_state # format for chatbot display
|
293 |
+
formatted_history = []
|
294 |
+
for message in text_chatbot_history:
|
295 |
+
formatted_history.append((message["content"] if message["role"] == "user" else None, message["content"] if message["role"] == "assistant" else None))
|
296 |
+
|
297 |
+
|
298 |
+
return formatted_history, updated_text_state, chatbot_type_state, gr.ChatInterface.update(visible=True), gr.Chatbot.update(visible=False) # Show text interface, hide vision chatbot
|
299 |
+
|
300 |
+
|
301 |
+
send_button.click(
|
302 |
+
send_message,
|
303 |
+
inputs=[image_input, text_input, chatbot_type_state, text_state, vision_state,
|
304 |
+
text_temperature_slider, text_repetition_penalty_slider, text_top_p_slider, text_top_k_slider, text_max_new_tokens_slider,
|
305 |
+
vision_temperature_slider, vision_top_p_slider, vision_top_k_slider, vision_max_tokens_slider],
|
306 |
+
outputs=[chatbot, vision_state, chatbot_type_state, gr.ChatInterface(), gr.Chatbot()] # Dummy ChatInterface output, real Chatbot output
|
307 |
+
)
|
308 |
+
|
309 |
+
clear_button.click(
|
310 |
+
clear_chat,
|
311 |
+
inputs=None,
|
312 |
+
outputs=[chatbot, vision_state, text_input, image_input, text_state] # Added text_state to clear
|
313 |
+
)
|
314 |
+
|
315 |
+
|
316 |
+
gr.Examples(
|
317 |
+
examples=[
|
318 |
+
["Explain the concept of quantum computing to someone with no background in physics or computer science.", None],
|
319 |
+
["What is OpenShift?", None],
|
320 |
+
["What's the importance of low latency inference?", None],
|
321 |
+
["Help me boost productivity habits.", None],
|
322 |
+
[
|
323 |
+
"""Explain the following code in a concise manner:
|
324 |
+
|
325 |
+
```java
|
326 |
+
import java.util.ArrayList;
|
327 |
+
import java.util.List;
|
328 |
+
|
329 |
+
public class Main {
|
330 |
+
|
331 |
+
public static void main(String[] args) {
|
332 |
+
int[] arr = {1, 5, 3, 4, 2};
|
333 |
+
int diff = 3;
|
334 |
+
List<Pair> pairs = findPairs(arr, diff);
|
335 |
+
for (Pair pair : pairs) {
|
336 |
+
System.out.println(pair.x + " " + pair.y);
|
337 |
+
}
|
338 |
+
}
|
339 |
+
|
340 |
+
public static List<Pair> findPairs(int[] arr, int diff) {
|
341 |
+
List<Pair> pairs = new ArrayList<>();
|
342 |
+
for (int i = 0; i < arr.length; i++) {
|
343 |
+
for (int j = i + 1; j < arr.length; j++) {
|
344 |
+
if (Math.abs(arr[i] - arr[j]) < diff) {
|
345 |
+
pairs.add(new Pair(arr[i], arr[j]));
|
346 |
+
}
|
347 |
+
}
|
348 |
+
}
|
349 |
+
|
350 |
+
return pairs;
|
351 |
+
}
|
352 |
+
}
|
353 |
+
|
354 |
+
class Pair {
|
355 |
+
int x;
|
356 |
+
int y;
|
357 |
+
public Pair(int x, int y) {
|
358 |
+
this.x = x;
|
359 |
+
this.y = y;
|
360 |
+
}
|
361 |
+
}
|
362 |
+
```""", None
|
363 |
+
],
|
364 |
+
[
|
365 |
+
"""Generate a Java code block from the following explanation:
|
366 |
+
|
367 |
+
The code in the Main class finds all pairs in an array whose absolute difference is less than a given value.
|
368 |
+
|
369 |
+
The findPairs method takes two arguments: an array of integers and a difference value. It iterates over the array and compares each element to every other element in the array. If the absolute difference between the two elements is less than the difference value, a new Pair object is created and added to a list.
|
370 |
+
|
371 |
+
The Pair class is a simple data structure that stores two integers.
|
372 |
+
|
373 |
+
The main method creates an array of integers, initializes the difference value, and calls the findPairs method to find all pairs in the array. Finally, the code iterates over the list of pairs and prints each pair to the console.""" , None # noqa: E501
|
374 |
+
],
|
375 |
+
["What is in this image?", "https://raw.githubusercontent.com/gradio-app/gradio/main/test/test_files/bus.png"] # Vision example
|
376 |
+
],
|
377 |
+
inputs=[text_input, image_input],
|
378 |
+
example_labels=[
|
379 |
+
"Explain quantum computing",
|
380 |
+
"What is OpenShift?",
|
381 |
+
"Importance of low latency inference",
|
382 |
+
"Boosting productivity habits",
|
383 |
+
"Explain and document your code",
|
384 |
+
"Generate Java Code",
|
385 |
+
"Vision Example: What is in this image?"
|
386 |
+
],
|
387 |
+
cache_examples=False,
|
388 |
+
)
|
389 |
+
|
390 |
+
|
391 |
+
if __name__ == "__main__":
|
392 |
+
demo.queue().launch()
|
src/app_head.html
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<link
|
2 |
+
rel="stylesheet"
|
3 |
+
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
|
4 |
+
/>
|
5 |
+
<script
|
6 |
+
async
|
7 |
+
src="https://www.googletagmanager.com/gtag/js?id=G-C6LFT227RC"
|
8 |
+
></script>
|
9 |
+
<script>
|
10 |
+
window.dataLayer = window.dataLayer || [];
|
11 |
+
function gtag() {
|
12 |
+
dataLayer.push(arguments);
|
13 |
+
}
|
14 |
+
gtag("js", new Date());
|
15 |
+
gtag("config", "G-C6LFT227RC");
|
16 |
+
</script>
|
src/themes/carbon.py
ADDED
@@ -0,0 +1,147 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""IBM Carbon theme for gradio demos.
|
2 |
+
|
3 |
+
This version builds on top of the Carbon theme to make it more playful with rounded corners, a larger font family to
|
4 |
+
enhance readability, and the IBM Cool Gray color palette for better consistency with other IBM Research demos, such as
|
5 |
+
Bee.
|
6 |
+
"""
|
7 |
+
|
8 |
+
import gradio as gr
|
9 |
+
from gradio.themes.utils import sizes
|
10 |
+
|
11 |
+
theme = gr.themes.Base(
|
12 |
+
primary_hue=gr.themes.Color(
|
13 |
+
c100="#EDF5FF",
|
14 |
+
c200="#D0E2FF",
|
15 |
+
c300="#A6C8FF",
|
16 |
+
c400="#78A9FF",
|
17 |
+
c50="#F9F9FB",
|
18 |
+
c500="#4589FF",
|
19 |
+
c600="#0F62FE",
|
20 |
+
c700="#0043CE",
|
21 |
+
c800="#002D9C",
|
22 |
+
c900="#001D6C",
|
23 |
+
c950="#001141",
|
24 |
+
),
|
25 |
+
secondary_hue=gr.themes.Color(
|
26 |
+
c100="#EDF5FF",
|
27 |
+
c200="#D0E2FF",
|
28 |
+
c300="#A6C8FF",
|
29 |
+
c400="#78A9FF",
|
30 |
+
c50="#F9F9FB",
|
31 |
+
c500="#4589FF",
|
32 |
+
c600="#0F62FE",
|
33 |
+
c700="#0043CE",
|
34 |
+
c800="#002D9C",
|
35 |
+
c900="#001D6C",
|
36 |
+
c950="#001141",
|
37 |
+
),
|
38 |
+
neutral_hue=gr.themes.Color(
|
39 |
+
c100="#F2F4F8",
|
40 |
+
c200="#DDE1E6",
|
41 |
+
c300="#C1C7CD",
|
42 |
+
c400="#A2A9B0",
|
43 |
+
c50="#F9F9FB",
|
44 |
+
c500="#878D96",
|
45 |
+
c600="#697077",
|
46 |
+
c700="#4D5358",
|
47 |
+
c800="#393939",
|
48 |
+
c900="#21272A",
|
49 |
+
c950="#121619",
|
50 |
+
),
|
51 |
+
spacing_size=sizes.spacing_md, # change spacing to default size
|
52 |
+
radius_size=sizes.radius_md, # change spacing to default size and Keep Radius to make demo feel more playful
|
53 |
+
text_size=sizes.text_lg, # change fontsize to default size
|
54 |
+
# spacing_size: sizes.Size | str = sizes.spacing_md, #change spacing to default size
|
55 |
+
# radius_size: sizes.Size | str = sizes.radius_md, #change spacing to default size and Keep Radius to make
|
56 |
+
# demo feel more playful
|
57 |
+
# text_size: sizes.Size | str = sizes.text_lg, #change fontsize to default size
|
58 |
+
font=["IBM Plex Sans", "ui-sans-serif", "system-ui", "sans-serif"], # update font
|
59 |
+
font_mono=["IBM Plex Mono", "ui-monospace", "Consolas", "monospace"], # update font
|
60 |
+
).set(
|
61 |
+
# Colors
|
62 |
+
background_fill_primary="*neutral_100", # Coolgray10 background
|
63 |
+
background_fill_primary_dark="*neutral_950", # Coolgray95 background for dark mode
|
64 |
+
slider_color="*primary_600", # Blue60
|
65 |
+
slider_color_dark="*primary_500", # Blue50
|
66 |
+
# Shadows
|
67 |
+
shadow_drop="0 1px 4px 0 rgb(0 0 0 / 0.1)",
|
68 |
+
shadow_drop_lg="0 2px 5px 0 rgb(0 0 0 / 0.1)",
|
69 |
+
# Block Labels
|
70 |
+
block_background_fill="white",
|
71 |
+
block_label_background_fill="white", # same color as blockback gound fill
|
72 |
+
block_label_radius="*radius_md",
|
73 |
+
block_label_text_size="*text_md",
|
74 |
+
block_label_text_weight="600",
|
75 |
+
block_label_text_color="black",
|
76 |
+
block_label_text_color_dark="white",
|
77 |
+
block_title_radius="*block_label_radius",
|
78 |
+
block_title_background_fill="*block_label_background_fill",
|
79 |
+
block_title_text_weight="600",
|
80 |
+
block_title_text_color="black",
|
81 |
+
block_title_text_color_dark="white",
|
82 |
+
block_label_margin="*spacing_md",
|
83 |
+
# Inputs
|
84 |
+
input_background_fill="white",
|
85 |
+
input_background_fill_dark="*block-background-fill",
|
86 |
+
input_border_color="*neutral_100",
|
87 |
+
input_shadow="*shadow_drop",
|
88 |
+
input_shadow_focus="*shadow_drop_lg",
|
89 |
+
checkbox_shadow="none",
|
90 |
+
# Buttons
|
91 |
+
shadow_spread="6px",
|
92 |
+
button_primary_shadow="*shadow_drop_lg",
|
93 |
+
button_primary_shadow_hover="*shadow_drop_lg",
|
94 |
+
button_primary_shadow_active="*shadow_inset",
|
95 |
+
button_secondary_shadow="*shadow_drop_lg",
|
96 |
+
button_secondary_shadow_hover="*shadow_drop_lg",
|
97 |
+
button_secondary_shadow_active="*shadow_inset",
|
98 |
+
checkbox_label_shadow="*shadow_drop_lg",
|
99 |
+
button_primary_background_fill="*primary_600",
|
100 |
+
button_primary_background_fill_hover="*primary_500",
|
101 |
+
button_primary_background_fill_hover_dark="*primary_500",
|
102 |
+
button_primary_text_color="white",
|
103 |
+
button_secondary_background_fill="white",
|
104 |
+
button_secondary_background_fill_hover="*neutral_100",
|
105 |
+
button_secondary_background_fill_dark="*neutral_800", # Secondary cool gray 80
|
106 |
+
button_secondary_background_fill_hover_dark="*primary_500",
|
107 |
+
button_secondary_text_color="*neutral_800",
|
108 |
+
button_cancel_background_fill="*button_secondary_background_fill",
|
109 |
+
button_cancel_background_fill_hover="*button_secondary_background_fill_hover",
|
110 |
+
button_cancel_background_fill_hover_dark="*button_secondary_background_fill_hover",
|
111 |
+
button_cancel_text_color="*button_secondary_text_color",
|
112 |
+
checkbox_label_background_fill_selected="*primary_200",
|
113 |
+
checkbox_label_background_fill_selected_dark="*primary_500",
|
114 |
+
checkbox_border_width="1px",
|
115 |
+
checkbox_border_color="*neutral_200",
|
116 |
+
checkbox_background_color_dark="*neutral_700", # Jan 18 test to fix checkbox, radio button background color
|
117 |
+
checkbox_background_color_selected="*primary_600",
|
118 |
+
checkbox_background_color_selected_dark="*primary_500",
|
119 |
+
checkbox_border_color_focus="*primary_600",
|
120 |
+
checkbox_border_color_focus_dark="*primary_500",
|
121 |
+
checkbox_border_color_selected="*primary_600",
|
122 |
+
checkbox_border_color_selected_dark="*primary_500",
|
123 |
+
checkbox_label_text_color_selected="black",
|
124 |
+
# Borders
|
125 |
+
block_border_width="1px", # test example border
|
126 |
+
panel_border_width="1px",
|
127 |
+
# Chatbubble related colors
|
128 |
+
# light
|
129 |
+
# color_accent = "*secondary_400",
|
130 |
+
border_color_accent_subdued="*color_accent_soft", # chatbubble human border color, use Blue 20 as an accent color
|
131 |
+
color_accent_soft="*secondary_200", # chatbubble human color
|
132 |
+
# darkmode
|
133 |
+
# chatbubble human border color in darkmode, use Blue 20 as an accent color
|
134 |
+
border_color_accent_subdued_dark="*secondary_500",
|
135 |
+
color_accent_soft_dark="*secondary_500", # chatbubble human color in dark mode
|
136 |
+
# Chatbot related font
|
137 |
+
chatbot_text_size="*text_md", # make it larger
|
138 |
+
# additional dark mode related tweaks:
|
139 |
+
# block_background_fill_dark="*neutral_950", # Jan 18 test coolgray95 background for dark mode
|
140 |
+
block_label_background_fill_dark="*neutral_800", # same color as blockback gound fill
|
141 |
+
block_title_background_fill_dark="*block_label_background_fill",
|
142 |
+
# input_background_fill_dark="*neutral_800", #This attribute help match fill color cool gray 80 to match background
|
143 |
+
# however cause the problem for the general theme.
|
144 |
+
# input_shadow_dark="*shadow_drop", #Test if it could make the border without the color
|
145 |
+
# input_border_color_dark="*neutral_200",#add attribute for border Jan 18
|
146 |
+
checkbox_border_color_dark="*neutral_600", # Jan 18 test to fix border
|
147 |
+
)
|
src/themes/research_monochrome.py
ADDED
@@ -0,0 +1,152 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""IBM Research Monochrome theme for gradio demos.
|
2 |
+
|
3 |
+
This version is a variation of CarbonSoft style, where the primary button is dark gray to create monochrome style. This
|
4 |
+
version uses the style from Research demos such as Bee to make it more playful with rounded corners, a larger font
|
5 |
+
family to enhance readability, and the IBM Cool Gray color palette for better consistency with other IBM Research demos,
|
6 |
+
such as Bee.
|
7 |
+
"""
|
8 |
+
|
9 |
+
import gradio as gr
|
10 |
+
from gradio.themes.utils import sizes
|
11 |
+
|
12 |
+
theme = gr.themes.Base(
|
13 |
+
primary_hue=gr.themes.Color(
|
14 |
+
c100="#EDF5FF",
|
15 |
+
c200="#D0E2FF",
|
16 |
+
c300="#A6C8FF",
|
17 |
+
c400="#78A9FF",
|
18 |
+
c50="#F9F9FB",
|
19 |
+
c500="#4589FF",
|
20 |
+
c600="#0F62FE",
|
21 |
+
c700="#0043CE",
|
22 |
+
c800="#002D9C",
|
23 |
+
c900="#001D6C",
|
24 |
+
c950="#001141",
|
25 |
+
),
|
26 |
+
secondary_hue=gr.themes.Color(
|
27 |
+
c100="#EDF5FF",
|
28 |
+
c200="#D0E2FF",
|
29 |
+
c300="#A6C8FF",
|
30 |
+
c400="#78A9FF",
|
31 |
+
c50="#F9F9FB",
|
32 |
+
c500="#4589FF",
|
33 |
+
c600="#0F62FE",
|
34 |
+
c700="#0043CE",
|
35 |
+
c800="#002D9C",
|
36 |
+
c900="#001D6C",
|
37 |
+
c950="#001141",
|
38 |
+
),
|
39 |
+
neutral_hue=gr.themes.Color(
|
40 |
+
c100="#F2F4F8",
|
41 |
+
c200="#DDE1E6",
|
42 |
+
c300="#C1C7CD",
|
43 |
+
c400="#A2A9B0",
|
44 |
+
c50="#F9F9FB",
|
45 |
+
c500="#878D96",
|
46 |
+
c600="#697077",
|
47 |
+
c700="#4D5358",
|
48 |
+
c800="#393939",
|
49 |
+
c900="#21272A",
|
50 |
+
c950="#121619",
|
51 |
+
),
|
52 |
+
spacing_size=sizes.spacing_md, # change spacing to default size
|
53 |
+
radius_size=sizes.radius_md, # change spacing to default size and Keep Radius to make demo feel more playful
|
54 |
+
text_size=sizes.text_md, # change fontsize to default size
|
55 |
+
# spacing_size: sizes.Size | str = sizes.spacing_md, #change spacing to default size
|
56 |
+
# radius_size: sizes.Size | str = sizes.radius_md, #change spacing to default size and Keep Radius to make
|
57 |
+
# demo feel more playful
|
58 |
+
# text_size: sizes.Size | str = sizes.text_lg, #change fontsize to default size
|
59 |
+
font=["IBM Plex Sans", "ui-sans-serif", "system-ui", "sans-serif"], # update font
|
60 |
+
font_mono=["IBM Plex Mono", "ui-monospace", "Consolas", "monospace"], # update font
|
61 |
+
).set(
|
62 |
+
# Colors
|
63 |
+
background_fill_primary="*neutral_100", # Coolgray10 background
|
64 |
+
background_fill_primary_dark="*neutral_950", # Coolgray95 background for dark mode
|
65 |
+
# Change blue to black to create monochrome style
|
66 |
+
slider_color="*neutral_900",
|
67 |
+
slider_color_dark="*primary_500",
|
68 |
+
# Shadows
|
69 |
+
shadow_drop="0 1px 4px 0 rgb(0 0 0 / 0.1)",
|
70 |
+
shadow_drop_lg="0 2px 5px 0 rgb(0 0 0 / 0.1)",
|
71 |
+
# Block Labels
|
72 |
+
block_background_fill="white",
|
73 |
+
block_label_background_fill="white", # same color as blockback gound fill
|
74 |
+
block_label_radius="*radius_md",
|
75 |
+
block_label_text_size="*text_md",
|
76 |
+
block_label_text_weight="600",
|
77 |
+
block_label_text_color="black",
|
78 |
+
block_label_text_color_dark="white",
|
79 |
+
block_title_radius="*block_label_radius",
|
80 |
+
block_title_background_fill="*block_label_background_fill",
|
81 |
+
block_title_text_weight="400",
|
82 |
+
block_title_text_color="black",
|
83 |
+
block_title_text_color_dark="white",
|
84 |
+
block_label_margin="*spacing_md",
|
85 |
+
# Inputs
|
86 |
+
input_background_fill="white",
|
87 |
+
input_background_fill_dark="*block-background-fill",
|
88 |
+
input_border_color="*neutral_100",
|
89 |
+
input_shadow="*shadow_drop",
|
90 |
+
input_shadow_dark="0 1px 4px #000",
|
91 |
+
input_shadow_focus="*shadow_drop_lg",
|
92 |
+
checkbox_shadow="none",
|
93 |
+
# Buttons
|
94 |
+
shadow_spread="6px",
|
95 |
+
button_primary_shadow="*shadow_drop_lg",
|
96 |
+
button_primary_shadow_hover="*shadow_drop_lg",
|
97 |
+
button_primary_shadow_active="*shadow_inset",
|
98 |
+
button_secondary_shadow="*shadow_drop_lg",
|
99 |
+
button_secondary_shadow_hover="*shadow_drop_lg",
|
100 |
+
button_secondary_shadow_active="*shadow_inset",
|
101 |
+
checkbox_label_shadow="*shadow_drop_lg",
|
102 |
+
# Change blue to black to create monochrome style
|
103 |
+
button_primary_background_fill="*neutral_900",
|
104 |
+
button_primary_background_fill_dark="*neutral_600",
|
105 |
+
button_primary_background_fill_hover="*neutral_700",
|
106 |
+
button_primary_background_fill_hover_dark="*primary_500", # hover to be blue
|
107 |
+
button_primary_text_color="white",
|
108 |
+
button_secondary_background_fill="white",
|
109 |
+
button_secondary_background_fill_hover="*neutral_100",
|
110 |
+
button_secondary_background_fill_dark="*neutral_800", # Secondary cool gray 80
|
111 |
+
button_secondary_background_fill_hover_dark="*primary_500",
|
112 |
+
button_secondary_text_color="*neutral_800",
|
113 |
+
button_cancel_background_fill="*button_secondary_background_fill",
|
114 |
+
button_cancel_background_fill_hover="*button_secondary_background_fill_hover",
|
115 |
+
button_cancel_background_fill_hover_dark="*button_secondary_background_fill_hover",
|
116 |
+
button_cancel_text_color="*button_secondary_text_color",
|
117 |
+
checkbox_label_background_fill_selected="*primary_200",
|
118 |
+
checkbox_label_background_fill_selected_dark="*primary_500",
|
119 |
+
checkbox_border_width="1px",
|
120 |
+
checkbox_border_color="*neutral_200",
|
121 |
+
checkbox_background_color_dark="*neutral_700", # Jan 18 test to fix checkbox, radio button background color
|
122 |
+
checkbox_background_color_selected="*primary_600",
|
123 |
+
checkbox_background_color_selected_dark="*primary_500",
|
124 |
+
checkbox_border_color_focus="*primary_600",
|
125 |
+
checkbox_border_color_focus_dark="*primary_500",
|
126 |
+
checkbox_border_color_selected="*primary_600",
|
127 |
+
checkbox_border_color_selected_dark="*primary_500",
|
128 |
+
checkbox_label_text_color_selected="black",
|
129 |
+
# Borders
|
130 |
+
block_border_width="1px", # test example border
|
131 |
+
panel_border_width="1px",
|
132 |
+
# Chatbubble related colors
|
133 |
+
# light
|
134 |
+
# color_accent = "*secondary_400",
|
135 |
+
border_color_accent_subdued="*color_accent_soft", # chatbubble human border color, use Blue 20 as an accent color
|
136 |
+
color_accent_soft="*secondary_200", # chatbubble human color
|
137 |
+
# darkmode
|
138 |
+
# chatbubble human border color in darkmode, use Blue 20 as an accent color
|
139 |
+
border_color_accent_subdued_dark="*secondary_500",
|
140 |
+
color_accent_soft_dark="*secondary_500", # chatbubble human color in dark mode
|
141 |
+
# Chatbot related font
|
142 |
+
chatbot_text_size="*text_md", # make it larger
|
143 |
+
# additional dark mode related tweaks:
|
144 |
+
# block_background_fill_dark="*neutral_950", # Jan 18 test coolgray95 background for dark mode
|
145 |
+
block_label_background_fill_dark="*neutral_800", # same color as blockback gound fill
|
146 |
+
block_title_background_fill_dark="*block_label_background_fill",
|
147 |
+
# input_background_fill_dark="*neutral_800", #This attribute help match fill color cool gray 80 to match background
|
148 |
+
# however cause the problem for the general theme.
|
149 |
+
# input_shadow_dark="*shadow_drop", #Test if it could make the border without the color
|
150 |
+
# input_border_color_dark="*neutral_200",#add attribute for border Jan 18
|
151 |
+
checkbox_border_color_dark="*neutral_600", # Jan 18 test to fix border
|
152 |
+
)
|