Upload 1820 files
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .gitattributes +2 -0
- ex/additional-networks/.github/workflows/typos.yml +21 -0
- ex/additional-networks/.gitignore +3 -0
- ex/additional-networks/LICENSE.txt +661 -0
- ex/additional-networks/README.md +199 -0
- ex/additional-networks/_typos.toml +9 -0
- ex/additional-networks/javascript/additional_networks.js +40 -0
- ex/additional-networks/models/lora/.keep +0 -0
- ex/additional-networks/preload.py +6 -0
- ex/additional-networks/scripts/additional_networks.py +398 -0
- ex/additional-networks/scripts/lora_compvis.py +631 -0
- ex/additional-networks/scripts/metadata_editor.py +484 -0
- ex/additional-networks/scripts/model_util.py +334 -0
- ex/additional-networks/scripts/safetensors_hack.py +116 -0
- ex/additional-networks/scripts/util.py +12 -0
- ex/additional-networks/scripts/xyz_grid_support.py +160 -0
- ex/additional-networks/style.css +9 -0
- ex/dynamic-prompts/.eslintrc.js +19 -0
- ex/dynamic-prompts/.github/CONTRIBUTING.md +130 -0
- ex/dynamic-prompts/.github/ISSUE_TEMPLATE/bug_report.md +31 -0
- ex/dynamic-prompts/.github/workflows/test.yml +28 -0
- ex/dynamic-prompts/.gitignore +7 -0
- ex/dynamic-prompts/.pre-commit-config.yaml +20 -0
- ex/dynamic-prompts/LICENSE +21 -0
- ex/dynamic-prompts/README.md +325 -0
- ex/dynamic-prompts/_tools/import_noodle_soup_prompts.py +87 -0
- ex/dynamic-prompts/collections/artists/European Art/baroque/baroque.txt +11 -0
- ex/dynamic-prompts/collections/artists/European Art/baroque/bentvueghels.txt +114 -0
- ex/dynamic-prompts/collections/artists/European Art/baroque/british_baroque_painters.txt +8 -0
- ex/dynamic-prompts/collections/artists/European Art/baroque/czech_baroque_painters.txt +5 -0
- ex/dynamic-prompts/collections/artists/European Art/baroque/danish_baroque_painters.txt +12 -0
- ex/dynamic-prompts/collections/artists/European Art/baroque/dutch_goldenage_painters.txt +828 -0
- ex/dynamic-prompts/collections/artists/European Art/baroque/flemish_baroque_painters.txt +199 -0
- ex/dynamic-prompts/collections/artists/European Art/baroque/french_baroque_painters.txt +54 -0
- ex/dynamic-prompts/collections/artists/European Art/baroque/german_baroque_painters.txt +60 -0
- ex/dynamic-prompts/collections/artists/European Art/baroque/greek_baroque_painters.txt +13 -0
- ex/dynamic-prompts/collections/artists/European Art/baroque/italian_baroque_painters.txt +198 -0
- ex/dynamic-prompts/collections/artists/European Art/baroque/netherlandish_baroque_painters.txt +2 -0
- ex/dynamic-prompts/collections/artists/European Art/baroque/quadratura.txt +74 -0
- ex/dynamic-prompts/collections/artists/European Art/baroque/rococco.txt +86 -0
- ex/dynamic-prompts/collections/artists/European Art/baroque/spanish_baroque_painters.txt +157 -0
- ex/dynamic-prompts/collections/artists/European Art/classical/classical.txt +9 -0
- ex/dynamic-prompts/collections/artists/European Art/medieval/gothic.txt +95 -0
- ex/dynamic-prompts/collections/artists/European Art/medieval/medieval.txt +3 -0
- ex/dynamic-prompts/collections/artists/European Art/medieval/romanesque.txt +33 -0
- ex/dynamic-prompts/collections/artists/European Art/modern/abstract_expressionism/abstract_expressionism.txt +395 -0
- ex/dynamic-prompts/collections/artists/European Art/modern/american_impressionism.txt +88 -0
- ex/dynamic-prompts/collections/artists/European Art/modern/art_nouveau.txt +145 -0
- ex/dynamic-prompts/collections/artists/European Art/modern/cloisonnism.txt +3 -0
- ex/dynamic-prompts/collections/artists/European Art/modern/cobs_art_colony.txt +19 -0
.gitattributes
CHANGED
@@ -34,3 +34,5 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
34 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
35 |
Alice[[:space:]]Tendou.png filter=lfs diff=lfs merge=lfs -text
|
36 |
CoopFellatio.png filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
34 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
35 |
Alice[[:space:]]Tendou.png filter=lfs diff=lfs merge=lfs -text
|
36 |
CoopFellatio.png filter=lfs diff=lfs merge=lfs -text
|
37 |
+
ex/dynamic-prompts/images/weighting-colours.png filter=lfs diff=lfs merge=lfs -text
|
38 |
+
ex/dynamic-prompts/images/weighting-us-population.png filter=lfs diff=lfs merge=lfs -text
|
ex/additional-networks/.github/workflows/typos.yml
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
---
|
2 |
+
# yamllint disable rule:line-length
|
3 |
+
name: Typos
|
4 |
+
|
5 |
+
on: # yamllint disable-line rule:truthy
|
6 |
+
push:
|
7 |
+
pull_request:
|
8 |
+
types:
|
9 |
+
- opened
|
10 |
+
- synchronize
|
11 |
+
- reopened
|
12 |
+
|
13 |
+
jobs:
|
14 |
+
build:
|
15 |
+
runs-on: ubuntu-latest
|
16 |
+
|
17 |
+
steps:
|
18 |
+
- uses: actions/checkout@v3
|
19 |
+
|
20 |
+
- name: typos-action
|
21 |
+
uses: crate-ci/typos@v1.13.10
|
ex/additional-networks/.gitignore
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
__pycache__
|
2 |
+
models/
|
3 |
+
/hashes.json
|
ex/additional-networks/LICENSE.txt
ADDED
@@ -0,0 +1,661 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
GNU AFFERO GENERAL PUBLIC LICENSE
|
2 |
+
Version 3, 19 November 2007
|
3 |
+
|
4 |
+
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
5 |
+
Everyone is permitted to copy and distribute verbatim copies
|
6 |
+
of this license document, but changing it is not allowed.
|
7 |
+
|
8 |
+
Preamble
|
9 |
+
|
10 |
+
The GNU Affero General Public License is a free, copyleft license for
|
11 |
+
software and other kinds of works, specifically designed to ensure
|
12 |
+
cooperation with the community in the case of network server software.
|
13 |
+
|
14 |
+
The licenses for most software and other practical works are designed
|
15 |
+
to take away your freedom to share and change the works. By contrast,
|
16 |
+
our General Public Licenses are intended to guarantee your freedom to
|
17 |
+
share and change all versions of a program--to make sure it remains free
|
18 |
+
software for all its users.
|
19 |
+
|
20 |
+
When we speak of free software, we are referring to freedom, not
|
21 |
+
price. Our General Public Licenses are designed to make sure that you
|
22 |
+
have the freedom to distribute copies of free software (and charge for
|
23 |
+
them if you wish), that you receive source code or can get it if you
|
24 |
+
want it, that you can change the software or use pieces of it in new
|
25 |
+
free programs, and that you know you can do these things.
|
26 |
+
|
27 |
+
Developers that use our General Public Licenses protect your rights
|
28 |
+
with two steps: (1) assert copyright on the software, and (2) offer
|
29 |
+
you this License which gives you legal permission to copy, distribute
|
30 |
+
and/or modify the software.
|
31 |
+
|
32 |
+
A secondary benefit of defending all users' freedom is that
|
33 |
+
improvements made in alternate versions of the program, if they
|
34 |
+
receive widespread use, become available for other developers to
|
35 |
+
incorporate. Many developers of free software are heartened and
|
36 |
+
encouraged by the resulting cooperation. However, in the case of
|
37 |
+
software used on network servers, this result may fail to come about.
|
38 |
+
The GNU General Public License permits making a modified version and
|
39 |
+
letting the public access it on a server without ever releasing its
|
40 |
+
source code to the public.
|
41 |
+
|
42 |
+
The GNU Affero General Public License is designed specifically to
|
43 |
+
ensure that, in such cases, the modified source code becomes available
|
44 |
+
to the community. It requires the operator of a network server to
|
45 |
+
provide the source code of the modified version running there to the
|
46 |
+
users of that server. Therefore, public use of a modified version, on
|
47 |
+
a publicly accessible server, gives the public access to the source
|
48 |
+
code of the modified version.
|
49 |
+
|
50 |
+
An older license, called the Affero General Public License and
|
51 |
+
published by Affero, was designed to accomplish similar goals. This is
|
52 |
+
a different license, not a version of the Affero GPL, but Affero has
|
53 |
+
released a new version of the Affero GPL which permits relicensing under
|
54 |
+
this license.
|
55 |
+
|
56 |
+
The precise terms and conditions for copying, distribution and
|
57 |
+
modification follow.
|
58 |
+
|
59 |
+
TERMS AND CONDITIONS
|
60 |
+
|
61 |
+
0. Definitions.
|
62 |
+
|
63 |
+
"This License" refers to version 3 of the GNU Affero General Public License.
|
64 |
+
|
65 |
+
"Copyright" also means copyright-like laws that apply to other kinds of
|
66 |
+
works, such as semiconductor masks.
|
67 |
+
|
68 |
+
"The Program" refers to any copyrightable work licensed under this
|
69 |
+
License. Each licensee is addressed as "you". "Licensees" and
|
70 |
+
"recipients" may be individuals or organizations.
|
71 |
+
|
72 |
+
To "modify" a work means to copy from or adapt all or part of the work
|
73 |
+
in a fashion requiring copyright permission, other than the making of an
|
74 |
+
exact copy. The resulting work is called a "modified version" of the
|
75 |
+
earlier work or a work "based on" the earlier work.
|
76 |
+
|
77 |
+
A "covered work" means either the unmodified Program or a work based
|
78 |
+
on the Program.
|
79 |
+
|
80 |
+
To "propagate" a work means to do anything with it that, without
|
81 |
+
permission, would make you directly or secondarily liable for
|
82 |
+
infringement under applicable copyright law, except executing it on a
|
83 |
+
computer or modifying a private copy. Propagation includes copying,
|
84 |
+
distribution (with or without modification), making available to the
|
85 |
+
public, and in some countries other activities as well.
|
86 |
+
|
87 |
+
To "convey" a work means any kind of propagation that enables other
|
88 |
+
parties to make or receive copies. Mere interaction with a user through
|
89 |
+
a computer network, with no transfer of a copy, is not conveying.
|
90 |
+
|
91 |
+
An interactive user interface displays "Appropriate Legal Notices"
|
92 |
+
to the extent that it includes a convenient and prominently visible
|
93 |
+
feature that (1) displays an appropriate copyright notice, and (2)
|
94 |
+
tells the user that there is no warranty for the work (except to the
|
95 |
+
extent that warranties are provided), that licensees may convey the
|
96 |
+
work under this License, and how to view a copy of this License. If
|
97 |
+
the interface presents a list of user commands or options, such as a
|
98 |
+
menu, a prominent item in the list meets this criterion.
|
99 |
+
|
100 |
+
1. Source Code.
|
101 |
+
|
102 |
+
The "source code" for a work means the preferred form of the work
|
103 |
+
for making modifications to it. "Object code" means any non-source
|
104 |
+
form of a work.
|
105 |
+
|
106 |
+
A "Standard Interface" means an interface that either is an official
|
107 |
+
standard defined by a recognized standards body, or, in the case of
|
108 |
+
interfaces specified for a particular programming language, one that
|
109 |
+
is widely used among developers working in that language.
|
110 |
+
|
111 |
+
The "System Libraries" of an executable work include anything, other
|
112 |
+
than the work as a whole, that (a) is included in the normal form of
|
113 |
+
packaging a Major Component, but which is not part of that Major
|
114 |
+
Component, and (b) serves only to enable use of the work with that
|
115 |
+
Major Component, or to implement a Standard Interface for which an
|
116 |
+
implementation is available to the public in source code form. A
|
117 |
+
"Major Component", in this context, means a major essential component
|
118 |
+
(kernel, window system, and so on) of the specific operating system
|
119 |
+
(if any) on which the executable work runs, or a compiler used to
|
120 |
+
produce the work, or an object code interpreter used to run it.
|
121 |
+
|
122 |
+
The "Corresponding Source" for a work in object code form means all
|
123 |
+
the source code needed to generate, install, and (for an executable
|
124 |
+
work) run the object code and to modify the work, including scripts to
|
125 |
+
control those activities. However, it does not include the work's
|
126 |
+
System Libraries, or general-purpose tools or generally available free
|
127 |
+
programs which are used unmodified in performing those activities but
|
128 |
+
which are not part of the work. For example, Corresponding Source
|
129 |
+
includes interface definition files associated with source files for
|
130 |
+
the work, and the source code for shared libraries and dynamically
|
131 |
+
linked subprograms that the work is specifically designed to require,
|
132 |
+
such as by intimate data communication or control flow between those
|
133 |
+
subprograms and other parts of the work.
|
134 |
+
|
135 |
+
The Corresponding Source need not include anything that users
|
136 |
+
can regenerate automatically from other parts of the Corresponding
|
137 |
+
Source.
|
138 |
+
|
139 |
+
The Corresponding Source for a work in source code form is that
|
140 |
+
same work.
|
141 |
+
|
142 |
+
2. Basic Permissions.
|
143 |
+
|
144 |
+
All rights granted under this License are granted for the term of
|
145 |
+
copyright on the Program, and are irrevocable provided the stated
|
146 |
+
conditions are met. This License explicitly affirms your unlimited
|
147 |
+
permission to run the unmodified Program. The output from running a
|
148 |
+
covered work is covered by this License only if the output, given its
|
149 |
+
content, constitutes a covered work. This License acknowledges your
|
150 |
+
rights of fair use or other equivalent, as provided by copyright law.
|
151 |
+
|
152 |
+
You may make, run and propagate covered works that you do not
|
153 |
+
convey, without conditions so long as your license otherwise remains
|
154 |
+
in force. You may convey covered works to others for the sole purpose
|
155 |
+
of having them make modifications exclusively for you, or provide you
|
156 |
+
with facilities for running those works, provided that you comply with
|
157 |
+
the terms of this License in conveying all material for which you do
|
158 |
+
not control copyright. Those thus making or running the covered works
|
159 |
+
for you must do so exclusively on your behalf, under your direction
|
160 |
+
and control, on terms that prohibit them from making any copies of
|
161 |
+
your copyrighted material outside their relationship with you.
|
162 |
+
|
163 |
+
Conveying under any other circumstances is permitted solely under
|
164 |
+
the conditions stated below. Sublicensing is not allowed; section 10
|
165 |
+
makes it unnecessary.
|
166 |
+
|
167 |
+
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
168 |
+
|
169 |
+
No covered work shall be deemed part of an effective technological
|
170 |
+
measure under any applicable law fulfilling obligations under article
|
171 |
+
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
172 |
+
similar laws prohibiting or restricting circumvention of such
|
173 |
+
measures.
|
174 |
+
|
175 |
+
When you convey a covered work, you waive any legal power to forbid
|
176 |
+
circumvention of technological measures to the extent such circumvention
|
177 |
+
is effected by exercising rights under this License with respect to
|
178 |
+
the covered work, and you disclaim any intention to limit operation or
|
179 |
+
modification of the work as a means of enforcing, against the work's
|
180 |
+
users, your or third parties' legal rights to forbid circumvention of
|
181 |
+
technological measures.
|
182 |
+
|
183 |
+
4. Conveying Verbatim Copies.
|
184 |
+
|
185 |
+
You may convey verbatim copies of the Program's source code as you
|
186 |
+
receive it, in any medium, provided that you conspicuously and
|
187 |
+
appropriately publish on each copy an appropriate copyright notice;
|
188 |
+
keep intact all notices stating that this License and any
|
189 |
+
non-permissive terms added in accord with section 7 apply to the code;
|
190 |
+
keep intact all notices of the absence of any warranty; and give all
|
191 |
+
recipients a copy of this License along with the Program.
|
192 |
+
|
193 |
+
You may charge any price or no price for each copy that you convey,
|
194 |
+
and you may offer support or warranty protection for a fee.
|
195 |
+
|
196 |
+
5. Conveying Modified Source Versions.
|
197 |
+
|
198 |
+
You may convey a work based on the Program, or the modifications to
|
199 |
+
produce it from the Program, in the form of source code under the
|
200 |
+
terms of section 4, provided that you also meet all of these conditions:
|
201 |
+
|
202 |
+
a) The work must carry prominent notices stating that you modified
|
203 |
+
it, and giving a relevant date.
|
204 |
+
|
205 |
+
b) The work must carry prominent notices stating that it is
|
206 |
+
released under this License and any conditions added under section
|
207 |
+
7. This requirement modifies the requirement in section 4 to
|
208 |
+
"keep intact all notices".
|
209 |
+
|
210 |
+
c) You must license the entire work, as a whole, under this
|
211 |
+
License to anyone who comes into possession of a copy. This
|
212 |
+
License will therefore apply, along with any applicable section 7
|
213 |
+
additional terms, to the whole of the work, and all its parts,
|
214 |
+
regardless of how they are packaged. This License gives no
|
215 |
+
permission to license the work in any other way, but it does not
|
216 |
+
invalidate such permission if you have separately received it.
|
217 |
+
|
218 |
+
d) If the work has interactive user interfaces, each must display
|
219 |
+
Appropriate Legal Notices; however, if the Program has interactive
|
220 |
+
interfaces that do not display Appropriate Legal Notices, your
|
221 |
+
work need not make them do so.
|
222 |
+
|
223 |
+
A compilation of a covered work with other separate and independent
|
224 |
+
works, which are not by their nature extensions of the covered work,
|
225 |
+
and which are not combined with it such as to form a larger program,
|
226 |
+
in or on a volume of a storage or distribution medium, is called an
|
227 |
+
"aggregate" if the compilation and its resulting copyright are not
|
228 |
+
used to limit the access or legal rights of the compilation's users
|
229 |
+
beyond what the individual works permit. Inclusion of a covered work
|
230 |
+
in an aggregate does not cause this License to apply to the other
|
231 |
+
parts of the aggregate.
|
232 |
+
|
233 |
+
6. Conveying Non-Source Forms.
|
234 |
+
|
235 |
+
You may convey a covered work in object code form under the terms
|
236 |
+
of sections 4 and 5, provided that you also convey the
|
237 |
+
machine-readable Corresponding Source under the terms of this License,
|
238 |
+
in one of these ways:
|
239 |
+
|
240 |
+
a) Convey the object code in, or embodied in, a physical product
|
241 |
+
(including a physical distribution medium), accompanied by the
|
242 |
+
Corresponding Source fixed on a durable physical medium
|
243 |
+
customarily used for software interchange.
|
244 |
+
|
245 |
+
b) Convey the object code in, or embodied in, a physical product
|
246 |
+
(including a physical distribution medium), accompanied by a
|
247 |
+
written offer, valid for at least three years and valid for as
|
248 |
+
long as you offer spare parts or customer support for that product
|
249 |
+
model, to give anyone who possesses the object code either (1) a
|
250 |
+
copy of the Corresponding Source for all the software in the
|
251 |
+
product that is covered by this License, on a durable physical
|
252 |
+
medium customarily used for software interchange, for a price no
|
253 |
+
more than your reasonable cost of physically performing this
|
254 |
+
conveying of source, or (2) access to copy the
|
255 |
+
Corresponding Source from a network server at no charge.
|
256 |
+
|
257 |
+
c) Convey individual copies of the object code with a copy of the
|
258 |
+
written offer to provide the Corresponding Source. This
|
259 |
+
alternative is allowed only occasionally and noncommercially, and
|
260 |
+
only if you received the object code with such an offer, in accord
|
261 |
+
with subsection 6b.
|
262 |
+
|
263 |
+
d) Convey the object code by offering access from a designated
|
264 |
+
place (gratis or for a charge), and offer equivalent access to the
|
265 |
+
Corresponding Source in the same way through the same place at no
|
266 |
+
further charge. You need not require recipients to copy the
|
267 |
+
Corresponding Source along with the object code. If the place to
|
268 |
+
copy the object code is a network server, the Corresponding Source
|
269 |
+
may be on a different server (operated by you or a third party)
|
270 |
+
that supports equivalent copying facilities, provided you maintain
|
271 |
+
clear directions next to the object code saying where to find the
|
272 |
+
Corresponding Source. Regardless of what server hosts the
|
273 |
+
Corresponding Source, you remain obligated to ensure that it is
|
274 |
+
available for as long as needed to satisfy these requirements.
|
275 |
+
|
276 |
+
e) Convey the object code using peer-to-peer transmission, provided
|
277 |
+
you inform other peers where the object code and Corresponding
|
278 |
+
Source of the work are being offered to the general public at no
|
279 |
+
charge under subsection 6d.
|
280 |
+
|
281 |
+
A separable portion of the object code, whose source code is excluded
|
282 |
+
from the Corresponding Source as a System Library, need not be
|
283 |
+
included in conveying the object code work.
|
284 |
+
|
285 |
+
A "User Product" is either (1) a "consumer product", which means any
|
286 |
+
tangible personal property which is normally used for personal, family,
|
287 |
+
or household purposes, or (2) anything designed or sold for incorporation
|
288 |
+
into a dwelling. In determining whether a product is a consumer product,
|
289 |
+
doubtful cases shall be resolved in favor of coverage. For a particular
|
290 |
+
product received by a particular user, "normally used" refers to a
|
291 |
+
typical or common use of that class of product, regardless of the status
|
292 |
+
of the particular user or of the way in which the particular user
|
293 |
+
actually uses, or expects or is expected to use, the product. A product
|
294 |
+
is a consumer product regardless of whether the product has substantial
|
295 |
+
commercial, industrial or non-consumer uses, unless such uses represent
|
296 |
+
the only significant mode of use of the product.
|
297 |
+
|
298 |
+
"Installation Information" for a User Product means any methods,
|
299 |
+
procedures, authorization keys, or other information required to install
|
300 |
+
and execute modified versions of a covered work in that User Product from
|
301 |
+
a modified version of its Corresponding Source. The information must
|
302 |
+
suffice to ensure that the continued functioning of the modified object
|
303 |
+
code is in no case prevented or interfered with solely because
|
304 |
+
modification has been made.
|
305 |
+
|
306 |
+
If you convey an object code work under this section in, or with, or
|
307 |
+
specifically for use in, a User Product, and the conveying occurs as
|
308 |
+
part of a transaction in which the right of possession and use of the
|
309 |
+
User Product is transferred to the recipient in perpetuity or for a
|
310 |
+
fixed term (regardless of how the transaction is characterized), the
|
311 |
+
Corresponding Source conveyed under this section must be accompanied
|
312 |
+
by the Installation Information. But this requirement does not apply
|
313 |
+
if neither you nor any third party retains the ability to install
|
314 |
+
modified object code on the User Product (for example, the work has
|
315 |
+
been installed in ROM).
|
316 |
+
|
317 |
+
The requirement to provide Installation Information does not include a
|
318 |
+
requirement to continue to provide support service, warranty, or updates
|
319 |
+
for a work that has been modified or installed by the recipient, or for
|
320 |
+
the User Product in which it has been modified or installed. Access to a
|
321 |
+
network may be denied when the modification itself materially and
|
322 |
+
adversely affects the operation of the network or violates the rules and
|
323 |
+
protocols for communication across the network.
|
324 |
+
|
325 |
+
Corresponding Source conveyed, and Installation Information provided,
|
326 |
+
in accord with this section must be in a format that is publicly
|
327 |
+
documented (and with an implementation available to the public in
|
328 |
+
source code form), and must require no special password or key for
|
329 |
+
unpacking, reading or copying.
|
330 |
+
|
331 |
+
7. Additional Terms.
|
332 |
+
|
333 |
+
"Additional permissions" are terms that supplement the terms of this
|
334 |
+
License by making exceptions from one or more of its conditions.
|
335 |
+
Additional permissions that are applicable to the entire Program shall
|
336 |
+
be treated as though they were included in this License, to the extent
|
337 |
+
that they are valid under applicable law. If additional permissions
|
338 |
+
apply only to part of the Program, that part may be used separately
|
339 |
+
under those permissions, but the entire Program remains governed by
|
340 |
+
this License without regard to the additional permissions.
|
341 |
+
|
342 |
+
When you convey a copy of a covered work, you may at your option
|
343 |
+
remove any additional permissions from that copy, or from any part of
|
344 |
+
it. (Additional permissions may be written to require their own
|
345 |
+
removal in certain cases when you modify the work.) You may place
|
346 |
+
additional permissions on material, added by you to a covered work,
|
347 |
+
for which you have or can give appropriate copyright permission.
|
348 |
+
|
349 |
+
Notwithstanding any other provision of this License, for material you
|
350 |
+
add to a covered work, you may (if authorized by the copyright holders of
|
351 |
+
that material) supplement the terms of this License with terms:
|
352 |
+
|
353 |
+
a) Disclaiming warranty or limiting liability differently from the
|
354 |
+
terms of sections 15 and 16 of this License; or
|
355 |
+
|
356 |
+
b) Requiring preservation of specified reasonable legal notices or
|
357 |
+
author attributions in that material or in the Appropriate Legal
|
358 |
+
Notices displayed by works containing it; or
|
359 |
+
|
360 |
+
c) Prohibiting misrepresentation of the origin of that material, or
|
361 |
+
requiring that modified versions of such material be marked in
|
362 |
+
reasonable ways as different from the original version; or
|
363 |
+
|
364 |
+
d) Limiting the use for publicity purposes of names of licensors or
|
365 |
+
authors of the material; or
|
366 |
+
|
367 |
+
e) Declining to grant rights under trademark law for use of some
|
368 |
+
trade names, trademarks, or service marks; or
|
369 |
+
|
370 |
+
f) Requiring indemnification of licensors and authors of that
|
371 |
+
material by anyone who conveys the material (or modified versions of
|
372 |
+
it) with contractual assumptions of liability to the recipient, for
|
373 |
+
any liability that these contractual assumptions directly impose on
|
374 |
+
those licensors and authors.
|
375 |
+
|
376 |
+
All other non-permissive additional terms are considered "further
|
377 |
+
restrictions" within the meaning of section 10. If the Program as you
|
378 |
+
received it, or any part of it, contains a notice stating that it is
|
379 |
+
governed by this License along with a term that is a further
|
380 |
+
restriction, you may remove that term. If a license document contains
|
381 |
+
a further restriction but permits relicensing or conveying under this
|
382 |
+
License, you may add to a covered work material governed by the terms
|
383 |
+
of that license document, provided that the further restriction does
|
384 |
+
not survive such relicensing or conveying.
|
385 |
+
|
386 |
+
If you add terms to a covered work in accord with this section, you
|
387 |
+
must place, in the relevant source files, a statement of the
|
388 |
+
additional terms that apply to those files, or a notice indicating
|
389 |
+
where to find the applicable terms.
|
390 |
+
|
391 |
+
Additional terms, permissive or non-permissive, may be stated in the
|
392 |
+
form of a separately written license, or stated as exceptions;
|
393 |
+
the above requirements apply either way.
|
394 |
+
|
395 |
+
8. Termination.
|
396 |
+
|
397 |
+
You may not propagate or modify a covered work except as expressly
|
398 |
+
provided under this License. Any attempt otherwise to propagate or
|
399 |
+
modify it is void, and will automatically terminate your rights under
|
400 |
+
this License (including any patent licenses granted under the third
|
401 |
+
paragraph of section 11).
|
402 |
+
|
403 |
+
However, if you cease all violation of this License, then your
|
404 |
+
license from a particular copyright holder is reinstated (a)
|
405 |
+
provisionally, unless and until the copyright holder explicitly and
|
406 |
+
finally terminates your license, and (b) permanently, if the copyright
|
407 |
+
holder fails to notify you of the violation by some reasonable means
|
408 |
+
prior to 60 days after the cessation.
|
409 |
+
|
410 |
+
Moreover, your license from a particular copyright holder is
|
411 |
+
reinstated permanently if the copyright holder notifies you of the
|
412 |
+
violation by some reasonable means, this is the first time you have
|
413 |
+
received notice of violation of this License (for any work) from that
|
414 |
+
copyright holder, and you cure the violation prior to 30 days after
|
415 |
+
your receipt of the notice.
|
416 |
+
|
417 |
+
Termination of your rights under this section does not terminate the
|
418 |
+
licenses of parties who have received copies or rights from you under
|
419 |
+
this License. If your rights have been terminated and not permanently
|
420 |
+
reinstated, you do not qualify to receive new licenses for the same
|
421 |
+
material under section 10.
|
422 |
+
|
423 |
+
9. Acceptance Not Required for Having Copies.
|
424 |
+
|
425 |
+
You are not required to accept this License in order to receive or
|
426 |
+
run a copy of the Program. Ancillary propagation of a covered work
|
427 |
+
occurring solely as a consequence of using peer-to-peer transmission
|
428 |
+
to receive a copy likewise does not require acceptance. However,
|
429 |
+
nothing other than this License grants you permission to propagate or
|
430 |
+
modify any covered work. These actions infringe copyright if you do
|
431 |
+
not accept this License. Therefore, by modifying or propagating a
|
432 |
+
covered work, you indicate your acceptance of this License to do so.
|
433 |
+
|
434 |
+
10. Automatic Licensing of Downstream Recipients.
|
435 |
+
|
436 |
+
Each time you convey a covered work, the recipient automatically
|
437 |
+
receives a license from the original licensors, to run, modify and
|
438 |
+
propagate that work, subject to this License. You are not responsible
|
439 |
+
for enforcing compliance by third parties with this License.
|
440 |
+
|
441 |
+
An "entity transaction" is a transaction transferring control of an
|
442 |
+
organization, or substantially all assets of one, or subdividing an
|
443 |
+
organization, or merging organizations. If propagation of a covered
|
444 |
+
work results from an entity transaction, each party to that
|
445 |
+
transaction who receives a copy of the work also receives whatever
|
446 |
+
licenses to the work the party's predecessor in interest had or could
|
447 |
+
give under the previous paragraph, plus a right to possession of the
|
448 |
+
Corresponding Source of the work from the predecessor in interest, if
|
449 |
+
the predecessor has it or can get it with reasonable efforts.
|
450 |
+
|
451 |
+
You may not impose any further restrictions on the exercise of the
|
452 |
+
rights granted or affirmed under this License. For example, you may
|
453 |
+
not impose a license fee, royalty, or other charge for exercise of
|
454 |
+
rights granted under this License, and you may not initiate litigation
|
455 |
+
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
456 |
+
any patent claim is infringed by making, using, selling, offering for
|
457 |
+
sale, or importing the Program or any portion of it.
|
458 |
+
|
459 |
+
11. Patents.
|
460 |
+
|
461 |
+
A "contributor" is a copyright holder who authorizes use under this
|
462 |
+
License of the Program or a work on which the Program is based. The
|
463 |
+
work thus licensed is called the contributor's "contributor version".
|
464 |
+
|
465 |
+
A contributor's "essential patent claims" are all patent claims
|
466 |
+
owned or controlled by the contributor, whether already acquired or
|
467 |
+
hereafter acquired, that would be infringed by some manner, permitted
|
468 |
+
by this License, of making, using, or selling its contributor version,
|
469 |
+
but do not include claims that would be infringed only as a
|
470 |
+
consequence of further modification of the contributor version. For
|
471 |
+
purposes of this definition, "control" includes the right to grant
|
472 |
+
patent sublicenses in a manner consistent with the requirements of
|
473 |
+
this License.
|
474 |
+
|
475 |
+
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
476 |
+
patent license under the contributor's essential patent claims, to
|
477 |
+
make, use, sell, offer for sale, import and otherwise run, modify and
|
478 |
+
propagate the contents of its contributor version.
|
479 |
+
|
480 |
+
In the following three paragraphs, a "patent license" is any express
|
481 |
+
agreement or commitment, however denominated, not to enforce a patent
|
482 |
+
(such as an express permission to practice a patent or covenant not to
|
483 |
+
sue for patent infringement). To "grant" such a patent license to a
|
484 |
+
party means to make such an agreement or commitment not to enforce a
|
485 |
+
patent against the party.
|
486 |
+
|
487 |
+
If you convey a covered work, knowingly relying on a patent license,
|
488 |
+
and the Corresponding Source of the work is not available for anyone
|
489 |
+
to copy, free of charge and under the terms of this License, through a
|
490 |
+
publicly available network server or other readily accessible means,
|
491 |
+
then you must either (1) cause the Corresponding Source to be so
|
492 |
+
available, or (2) arrange to deprive yourself of the benefit of the
|
493 |
+
patent license for this particular work, or (3) arrange, in a manner
|
494 |
+
consistent with the requirements of this License, to extend the patent
|
495 |
+
license to downstream recipients. "Knowingly relying" means you have
|
496 |
+
actual knowledge that, but for the patent license, your conveying the
|
497 |
+
covered work in a country, or your recipient's use of the covered work
|
498 |
+
in a country, would infringe one or more identifiable patents in that
|
499 |
+
country that you have reason to believe are valid.
|
500 |
+
|
501 |
+
If, pursuant to or in connection with a single transaction or
|
502 |
+
arrangement, you convey, or propagate by procuring conveyance of, a
|
503 |
+
covered work, and grant a patent license to some of the parties
|
504 |
+
receiving the covered work authorizing them to use, propagate, modify
|
505 |
+
or convey a specific copy of the covered work, then the patent license
|
506 |
+
you grant is automatically extended to all recipients of the covered
|
507 |
+
work and works based on it.
|
508 |
+
|
509 |
+
A patent license is "discriminatory" if it does not include within
|
510 |
+
the scope of its coverage, prohibits the exercise of, or is
|
511 |
+
conditioned on the non-exercise of one or more of the rights that are
|
512 |
+
specifically granted under this License. You may not convey a covered
|
513 |
+
work if you are a party to an arrangement with a third party that is
|
514 |
+
in the business of distributing software, under which you make payment
|
515 |
+
to the third party based on the extent of your activity of conveying
|
516 |
+
the work, and under which the third party grants, to any of the
|
517 |
+
parties who would receive the covered work from you, a discriminatory
|
518 |
+
patent license (a) in connection with copies of the covered work
|
519 |
+
conveyed by you (or copies made from those copies), or (b) primarily
|
520 |
+
for and in connection with specific products or compilations that
|
521 |
+
contain the covered work, unless you entered into that arrangement,
|
522 |
+
or that patent license was granted, prior to 28 March 2007.
|
523 |
+
|
524 |
+
Nothing in this License shall be construed as excluding or limiting
|
525 |
+
any implied license or other defenses to infringement that may
|
526 |
+
otherwise be available to you under applicable patent law.
|
527 |
+
|
528 |
+
12. No Surrender of Others' Freedom.
|
529 |
+
|
530 |
+
If conditions are imposed on you (whether by court order, agreement or
|
531 |
+
otherwise) that contradict the conditions of this License, they do not
|
532 |
+
excuse you from the conditions of this License. If you cannot convey a
|
533 |
+
covered work so as to satisfy simultaneously your obligations under this
|
534 |
+
License and any other pertinent obligations, then as a consequence you may
|
535 |
+
not convey it at all. For example, if you agree to terms that obligate you
|
536 |
+
to collect a royalty for further conveying from those to whom you convey
|
537 |
+
the Program, the only way you could satisfy both those terms and this
|
538 |
+
License would be to refrain entirely from conveying the Program.
|
539 |
+
|
540 |
+
13. Remote Network Interaction; Use with the GNU General Public License.
|
541 |
+
|
542 |
+
Notwithstanding any other provision of this License, if you modify the
|
543 |
+
Program, your modified version must prominently offer all users
|
544 |
+
interacting with it remotely through a computer network (if your version
|
545 |
+
supports such interaction) an opportunity to receive the Corresponding
|
546 |
+
Source of your version by providing access to the Corresponding Source
|
547 |
+
from a network server at no charge, through some standard or customary
|
548 |
+
means of facilitating copying of software. This Corresponding Source
|
549 |
+
shall include the Corresponding Source for any work covered by version 3
|
550 |
+
of the GNU General Public License that is incorporated pursuant to the
|
551 |
+
following paragraph.
|
552 |
+
|
553 |
+
Notwithstanding any other provision of this License, you have
|
554 |
+
permission to link or combine any covered work with a work licensed
|
555 |
+
under version 3 of the GNU General Public License into a single
|
556 |
+
combined work, and to convey the resulting work. The terms of this
|
557 |
+
License will continue to apply to the part which is the covered work,
|
558 |
+
but the work with which it is combined will remain governed by version
|
559 |
+
3 of the GNU General Public License.
|
560 |
+
|
561 |
+
14. Revised Versions of this License.
|
562 |
+
|
563 |
+
The Free Software Foundation may publish revised and/or new versions of
|
564 |
+
the GNU Affero General Public License from time to time. Such new versions
|
565 |
+
will be similar in spirit to the present version, but may differ in detail to
|
566 |
+
address new problems or concerns.
|
567 |
+
|
568 |
+
Each version is given a distinguishing version number. If the
|
569 |
+
Program specifies that a certain numbered version of the GNU Affero General
|
570 |
+
Public License "or any later version" applies to it, you have the
|
571 |
+
option of following the terms and conditions either of that numbered
|
572 |
+
version or of any later version published by the Free Software
|
573 |
+
Foundation. If the Program does not specify a version number of the
|
574 |
+
GNU Affero General Public License, you may choose any version ever published
|
575 |
+
by the Free Software Foundation.
|
576 |
+
|
577 |
+
If the Program specifies that a proxy can decide which future
|
578 |
+
versions of the GNU Affero General Public License can be used, that proxy's
|
579 |
+
public statement of acceptance of a version permanently authorizes you
|
580 |
+
to choose that version for the Program.
|
581 |
+
|
582 |
+
Later license versions may give you additional or different
|
583 |
+
permissions. However, no additional obligations are imposed on any
|
584 |
+
author or copyright holder as a result of your choosing to follow a
|
585 |
+
later version.
|
586 |
+
|
587 |
+
15. Disclaimer of Warranty.
|
588 |
+
|
589 |
+
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
590 |
+
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
591 |
+
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
592 |
+
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
593 |
+
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
594 |
+
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
595 |
+
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
596 |
+
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
597 |
+
|
598 |
+
16. Limitation of Liability.
|
599 |
+
|
600 |
+
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
601 |
+
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
602 |
+
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
603 |
+
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
604 |
+
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
605 |
+
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
606 |
+
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
607 |
+
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
608 |
+
SUCH DAMAGES.
|
609 |
+
|
610 |
+
17. Interpretation of Sections 15 and 16.
|
611 |
+
|
612 |
+
If the disclaimer of warranty and limitation of liability provided
|
613 |
+
above cannot be given local legal effect according to their terms,
|
614 |
+
reviewing courts shall apply local law that most closely approximates
|
615 |
+
an absolute waiver of all civil liability in connection with the
|
616 |
+
Program, unless a warranty or assumption of liability accompanies a
|
617 |
+
copy of the Program in return for a fee.
|
618 |
+
|
619 |
+
END OF TERMS AND CONDITIONS
|
620 |
+
|
621 |
+
How to Apply These Terms to Your New Programs
|
622 |
+
|
623 |
+
If you develop a new program, and you want it to be of the greatest
|
624 |
+
possible use to the public, the best way to achieve this is to make it
|
625 |
+
free software which everyone can redistribute and change under these terms.
|
626 |
+
|
627 |
+
To do so, attach the following notices to the program. It is safest
|
628 |
+
to attach them to the start of each source file to most effectively
|
629 |
+
state the exclusion of warranty; and each file should have at least
|
630 |
+
the "copyright" line and a pointer to where the full notice is found.
|
631 |
+
|
632 |
+
<one line to give the program's name and a brief idea of what it does.>
|
633 |
+
Copyright (C) <year> <name of author>
|
634 |
+
|
635 |
+
This program is free software: you can redistribute it and/or modify
|
636 |
+
it under the terms of the GNU Affero General Public License as published by
|
637 |
+
the Free Software Foundation, either version 3 of the License, or
|
638 |
+
(at your option) any later version.
|
639 |
+
|
640 |
+
This program is distributed in the hope that it will be useful,
|
641 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
642 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
643 |
+
GNU Affero General Public License for more details.
|
644 |
+
|
645 |
+
You should have received a copy of the GNU Affero General Public License
|
646 |
+
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
647 |
+
|
648 |
+
Also add information on how to contact you by electronic and paper mail.
|
649 |
+
|
650 |
+
If your software can interact with users remotely through a computer
|
651 |
+
network, you should also make sure that it provides a way for users to
|
652 |
+
get its source. For example, if your program is a web application, its
|
653 |
+
interface could display a "Source" link that leads users to an archive
|
654 |
+
of the code. There are many ways you could offer source, and different
|
655 |
+
solutions will be better for different programs; see section 13 for the
|
656 |
+
specific requirements.
|
657 |
+
|
658 |
+
You should also get your employer (if you work as a programmer) or school,
|
659 |
+
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
660 |
+
For more information on this, and how to apply and follow the GNU AGPL, see
|
661 |
+
<https://www.gnu.org/licenses/>.
|
ex/additional-networks/README.md
ADDED
@@ -0,0 +1,199 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
## Additional Networks for generating images
|
2 |
+
|
3 |
+
日本語の文章は下のほうにあります。
|
4 |
+
|
5 |
+
[__Change History__](#change-history) is moved to the bottom of the page.
|
6 |
+
更新履歴は[ページ末尾](#change-history)に移しました。
|
7 |
+
|
8 |
+
__Stable Diffusion web UI now seems to support LoRA trained by ``sd-scripts``__ (SD 1.x based only, except Conv2d-3x3 LoRA). Thank you for great work!!!
|
9 |
+
|
10 |
+
Update: Support current version of [LoCon](https://github.com/KohakuBlueleaf/LoCon). __Thank you very much KohakuBlueleaf for your help!__
|
11 |
+
|
12 |
+
|
13 |
+
## About
|
14 |
+
|
15 |
+
This extension is for [AUTOMATIC1111's Stable Diffusion web UI](https://github.com/AUTOMATIC1111/stable-diffusion-webui), allows the Web UI to add some networks (e.g. LoRA) to the original Stable Diffusion model to generate images. Currently LoRA is supported. The addition is on-the-fly, the merging is not required.
|
16 |
+
|
17 |
+
This extension supports the LoRA models (*.ckpt or *.safetensors) trained by our scripts in [sd-scripts](https://github.com/kohya-ss/sd-scripts). The models from other LoRA implementations are not supported.
|
18 |
+
|
19 |
+
This extension does not support training.
|
20 |
+
|
21 |
+
Other networks other than LoRA may be supported in the future.
|
22 |
+
|
23 |
+
## Installation
|
24 |
+
|
25 |
+
1. Open "Extensions" tab.
|
26 |
+
1. Open "Install from URL" tab in the tab.
|
27 |
+
1. Enter URL of this repo to "URL for extension's git repository".
|
28 |
+
1. Press "Install" button.
|
29 |
+
1. Restart Web UI.
|
30 |
+
|
31 |
+
## How to use
|
32 |
+
|
33 |
+
Put the LoRA models (`*.pt`, `*.ckpt` or `*.safetensors`) inside the `sd-webui-additional-networks/models/LoRA` folder.
|
34 |
+
|
35 |
+
Open __"Additional Networks"__ panel from the left bottom of Web UI.
|
36 |
+
|
37 |
+
Press __"Refresh models"__ to update the models list.
|
38 |
+
|
39 |
+
Select __"LoRA"__ for __"Network module 1"__.
|
40 |
+
|
41 |
+
Choose __the name of the LoRA model file__ in __"Model 1"__.
|
42 |
+
|
43 |
+
Set __the weight__ of the model (negative weight might be working but unexpected.)
|
44 |
+
|
45 |
+
Repeat them for the module/model/weight 2 to 5 if you have other models. Models are applied in the order of 1 to 5.
|
46 |
+
|
47 |
+
You can generate images with the model with these additional networks.
|
48 |
+
|
49 |
+
## X/Y plot
|
50 |
+
|
51 |
+
If you use LoRA models to plot, put the comma separated list of the model names into ``AddNet Model X``
|
52 |
+
|
53 |
+

|
54 |
+
|
55 |
+
You can get the list of models with the button next to ``Values``. Please select any model in ``Model ?`` at ``Additional Networks`` in order to make the button work. Models in the same folder as the model will be listed.
|
56 |
+
|
57 |
+

|
58 |
+
|
59 |
+
The metadata of the model can be drawn as legends. Move to ``Settings`` tab, select ``Additional Networks`` at left bottom, and set ``Metadata to show``. Available values are in ``Network metadata`` textbox in ``Additional Networks`` tab.
|
60 |
+
|
61 |
+

|
62 |
+
|
63 |
+
## Specify target region of LoRA by mask (__experimental__)
|
64 |
+
|
65 |
+
Open `Extra args` and drop a mask image to `mask image`.
|
66 |
+
|
67 |
+
By specifying with the mask image, each LoRA model can be applied only to the specified region of the image. Currently, only three models (Models 1 to 3) can be masked.
|
68 |
+
|
69 |
+
The mask image is RGB image, with each channel (R, G and B) corresponding to LoRA models 1 to 3. Each channel can be overlapped. For example, yellow area (R and G) is applied to LoRA model 1 and 2. The range of values is 0 to 255, corresponding to a LoRA weight of 0 to 1.
|
70 |
+
|
71 |
+
It can be combined with ControlNet.
|
72 |
+
|
73 |
+
| |without ControlNet|with ControlNet|
|
74 |
+
|:----:|:----:|:----:|
|
75 |
+
|no LoRA|<img src="https://user-images.githubusercontent.com/52813779/223676928-362a68f0-b4c4-4905-9a5f-6646a39341f7.png" width="256">|<img src="https://user-images.githubusercontent.com/52813779/223677042-a7989dc8-741f-4d45-8328-be1f0bf08194.png" width="256">|
|
76 |
+
|with LoRA, no mask|<img src="https://user-images.githubusercontent.com/52813779/223677327-b4237ff9-1d36-4cd9-971b-a3434db6d0f9.png" width="256">|<img src="https://user-images.githubusercontent.com/52813779/223677380-ba74bca0-92c3-4c68-950f-0f96e439281e.png" width="256">|
|
77 |
+
|with Lora, with mask|<img src="https://user-images.githubusercontent.com/52813779/223677475-dff082c1-2a41-4d46-982d-db9655eb8bc2.png" width="256">|<img src="https://user-images.githubusercontent.com/52813779/223677518-0ae042ed-3baf-47f0-b8ca-3dd6805f7c2f.png" width="256">|
|
78 |
+
| |pose|mask|
|
79 |
+
| |<img src="https://user-images.githubusercontent.com/52813779/223677653-cfd7fb36-afc1-49e8-9253-4bc01c5dad99.png" width="256">|<img src="https://user-images.githubusercontent.com/52813779/223677672-5e2fc729-01ee-4c62-8457-2e125bb0e24f.png" width="256">
|
80 |
+
|
81 |
+
Sample images are generated with [wd-1-5-beta2-aesthetic-fp16.safetensors](https://huggingface.co/waifu-diffusion/wd-1-5-beta2) and three LoRAs: two character LoRAs (model 1 and 2, masked, weight=1.0) and one style LoRA (model 4, not masked, weight=0.8). Used ControlNet is [diff_control_wd15beta2_pose.safetensors](https://huggingface.co/furusu/ControlNet).
|
82 |
+
|
83 |
+
### Difference from 'Latent Couple extension' and 'Composable LoRA'
|
84 |
+
|
85 |
+
'Latent Couple extension' masks the output of U-Net for each sub-prompt (AND-separated prompts), while our implementation masks the output of LoRA at each layer of U-Net. The mask is resized according to the tensor shape of each layer, so the resolution is particularly coarse at the deeper layers.
|
86 |
+
|
87 |
+
'Composable LoRA' controls the area via 'Latent Couple extension' by switching LoRA on or off for each sub-prompt, but this implementation works alone.
|
88 |
+
|
89 |
+
This implementation does not work for all modules in LoRA (the modules associated with Text Encoder are not masked), and due to the coarse resolution, it is not possible to completely separate areas.
|
90 |
+
|
91 |
+
## この Web UI 拡張について
|
92 |
+
|
93 |
+
LoRA などのネットワークを元の Stable Diffusion に追加し、画像生成を行うための拡張です。現在は LoRA のみ対応しています。
|
94 |
+
|
95 |
+
この拡張で使えるのは[sd-scripts](https://github.com/kohya-ss/sd-scripts)リポジトリで学習した LoRA のモデル(\*.ckpt または \*.safetensors)です。他の LoRA リポジトリで学習したモデルは対応していません。
|
96 |
+
|
97 |
+
この拡張単体では学習はできません。
|
98 |
+
|
99 |
+
将来的に LoRA 以外のネットワークについてもサポートするかもしれません。
|
100 |
+
|
101 |
+
## インストール
|
102 |
+
|
103 |
+
1. Web UI で "Extensions" タブを開きます。
|
104 |
+
1. さらに "Install from URL" タブを開きます。
|
105 |
+
1. "URL for extension's git repository" 欄にこのリポジトリの URL を入れます。
|
106 |
+
1. "Install"ボタンを押してインストールします。
|
107 |
+
1. Web UI を再起動してください。
|
108 |
+
|
109 |
+
## 使用法
|
110 |
+
|
111 |
+
学習した LoRA のモデル(`*.pt`, `*.ckpt`, `*.safetensors`)を`sd-webui-additional-networks/models/LoRA`に置きます。
|
112 |
+
|
113 |
+
Web UI の左下のほうの __"Additional Networks"__ のパネルを開きます。
|
114 |
+
|
115 |
+
__"Network module 1"__ で __"LoRA"__ を選択してください。
|
116 |
+
|
117 |
+
__"Refresh models"__ で LoRA モデルのリストを更新します。
|
118 |
+
|
119 |
+
__"Model 1"__ に学習した LoRA のモデル名を選択します。
|
120 |
+
|
121 |
+
__"Weight"__ にこのモデルの __重み__ を指定します(負の値も指定できますがどんな効果があるかは未知数です)。
|
122 |
+
|
123 |
+
追加のモデルがある場合は 2~5 に指定してください。モデルは 1~5 の順番で適用されます。
|
124 |
+
|
125 |
+
以上を指定すると、それぞれのモデルが適用された状態で画像生成されます。
|
126 |
+
|
127 |
+
## X/Y plot
|
128 |
+
|
129 |
+
LoRAモデルをX/Y plotの値(選択対象)として使う場合は、カンマ区切りのモデルのリストを与える必要があります。
|
130 |
+
|
131 |
+

|
132 |
+
|
133 |
+
モデルのリストは選択肢の隣にあるボタンで取得できます。いずれかのモデルを ``Additional Networks`` の ``Model ?`` で選択しておいてください。そのモデルと同じフォルダにあるモデルの一覧が取得されます。
|
134 |
+
|
135 |
+

|
136 |
+
|
137 |
+
モデルのメタデータ(学習時のパラメータなど)をX/Y plotのラベルに使用できます。Web UI上部の ``Settings`` タブを開き、左下から ``Additional Networks`` を選び、 ``Metadata to show`` にカンマ区切りで項目名を指定してください(``ss_learning_rate, ss_num_epochs`` のような感じになります)。使える値は ``Additional Networks`` の ``Network metadata`` 欄にある値です。
|
138 |
+
|
139 |
+

|
140 |
+
|
141 |
+
## LoRA の領域別適用 __(実験的機能)__
|
142 |
+
|
143 |
+
適用する領域をマスク画像で指定することで、それぞれの LoRA モデルを画像の指定した部分にのみ適用することができます。現在はモデル1~3の3つのみ領域指定可能です。
|
144 |
+
|
145 |
+
マスク画像はカラーの画像で、RGBの各チャネルが LoRA モデル1から3に対応します。RGBの各チャネルは重ねることが可能です。たとえば黄色(RとGチャネル)の領域は、モデル1と2が有効になります。ピクセル値0から255がLoRAの適用率0から1に対応します(127なら重み0.5で適用するのと同じになります)。
|
146 |
+
|
147 |
+
マスク画像は生成画像サイズにリサイズされて適用されます。
|
148 |
+
|
149 |
+
ControlNetと組み合わせることも可能です(細かい位置指定にはControlNetとの組み合わせを推奨します)。
|
150 |
+
|
151 |
+
上のサンプルをご参照ください。
|
152 |
+
|
153 |
+
### Latent Couple extension、Composable LoRAとの違い
|
154 |
+
|
155 |
+
Latent Couple extension はサブプロンプト(ANDで区切られたプロンプト)ごとに、U-Net の出力をマスクしますが、当実装では U-Net の各層で LoRA の出力をマスクします。マスクは各層の���ンソル形状に応じてリサイズされるため、深い層では特に解像度が粗くなります。
|
156 |
+
|
157 |
+
Composable LoRA はサブプロンプトごとに LoRA の適用有無を切り替えることで Latent Couple extension を経由して影響範囲を制御しますが、当実装では単独で動作します。
|
158 |
+
|
159 |
+
当実装はすべての LoRA モジュールに作用するわけではなく(Text Encoder に関連する LoRA モジュールはマスクされません)、また解像度が粗いため、完全に領域を分離することはできません。
|
160 |
+
|
161 |
+
## Change History
|
162 |
+
|
163 |
+
- 6 Apr. 2023, 2023/4/6
|
164 |
+
- Fix an issue where the `Hires. fix` does not work with mask.
|
165 |
+
- 領域別LoRAでHires. fixが動作しない不具合を修正しました。
|
166 |
+
- 30 Mar. 2023, 2023/3/30
|
167 |
+
- Fix an issue where the `Save Metadata` button in the metadata editor does not work even if `Editing Enabled` is checked.
|
168 |
+
- メタデータエディタで `Save Metadata` ボタンが `Editing Enabled` をチェックしても有効にならない不具合を修正しました。
|
169 |
+
- 28 Mar. 2023, 2023/3/28
|
170 |
+
- Fix style for Gradio 3.22. Thanks to space-nuko!
|
171 |
+
- Please update Web UI to the latest version.
|
172 |
+
- Gradio 3.22 のスタイルに対応しました。space-nuko氏に感謝します。
|
173 |
+
- Web UIを最新版に更新願います。
|
174 |
+
- 11 Mar. 2023, 2023/3/11
|
175 |
+
- Leading spaces in each path in `Extra paths to scan for LoRA models` settings are ignored. Thanks to tsukimiya!
|
176 |
+
- 設定の `Extra paths to scan for LoRA models` の各ディレクトリ名の先頭スペースを無視するよう変更しました。tsukimiya氏に感謝します。
|
177 |
+
- 9 Mar. 2023, 2023/3/9: Release v0.5.1
|
178 |
+
- Fix the model saved with `bf16` causes an error. https://github.com/kohya-ss/sd-webui-additional-networks/issues/127
|
179 |
+
- Fix some Conv2d-3x3 LoRA modules are not effective. https://github.com/kohya-ss/sd-scripts/issues/275
|
180 |
+
- Fix LoRA modules with higher dim (rank) > 320 causes an error.
|
181 |
+
- `bf16` で学習されたモデルが読み込めない不具合を修正しました。 https://github.com/kohya-ss/sd-webui-additional-networks/issues/127
|
182 |
+
- いくつかの Conv2d-3x3 LoRA モジュールが有効にならない不具合を修正しました。 https://github.com/kohya-ss/sd-scripts/issues/275
|
183 |
+
- dim (rank) が 320 を超えるLoRAモデルが読み込めない不具合を修正しました。
|
184 |
+
- 8 Mar. 2023, 2023/3/8: Release v0.5.0
|
185 |
+
- Support current version of [LoCon](https://github.com/KohakuBlueleaf/LoCon). __Thank you very much KohakuBlueleaf for your help!__
|
186 |
+
- LoCon will be enhanced in the future. Compatibility for future versions is not guaranteed.
|
187 |
+
- Support dynamic LoRA: different dimensions (ranks) and alpha for each module.
|
188 |
+
- Support LoRA for Conv2d (extended to conv2d with a kernel size not 1x1).
|
189 |
+
- Add masked LoRA feature (experimental.)
|
190 |
+
- 現在のバージョンの [LoCon](https://github.com/KohakuBlueleaf/LoCon) をサポートしました。 KohakuBlueleaf 氏のご支援に深く感謝します。
|
191 |
+
- LoCon が将来的に拡張された場合、それらのバージョンでの互換性は保証できません。
|
192 |
+
- dynamic LoRA の機能を追加しました。各モジュールで異なる dimension (rank) や alpha を持つ LoRA が使えます。
|
193 |
+
- Conv2d 拡張 LoRA をサポートしました。カーネルサイズが1x1でない Conv2d を対象とした LoRA が使えます。
|
194 |
+
- LoRA の適用領域指定機能を追加しました(実験的機能)。
|
195 |
+
|
196 |
+
|
197 |
+
Please read [Releases](https://github.com/kohya-ss/sd-webui-additional-networks/releases) for recent updates.
|
198 |
+
最近の更新情報は [Release](https://github.com/kohya-ss/sd-webui-additional-networks/releases) をご覧ください。
|
199 |
+
|
ex/additional-networks/_typos.toml
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Files for typos
|
2 |
+
# Instruction: https://github.com/marketplace/actions/typos-action#getting-started
|
3 |
+
|
4 |
+
[default.extend-identifiers]
|
5 |
+
|
6 |
+
[default.extend-words]
|
7 |
+
|
8 |
+
[files]
|
9 |
+
extend-exclude = ["_typos.toml"]
|
ex/additional-networks/javascript/additional_networks.js
ADDED
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
function addnet_switch_to_txt2img(){
|
2 |
+
switch_to_txt2img();
|
3 |
+
setTimeout(function() { gradioApp().getElementById("additional_networks_txt2img").scrollIntoView(); }, 100);
|
4 |
+
return args_to_array(arguments);
|
5 |
+
}
|
6 |
+
|
7 |
+
function addnet_switch_to_img2img(){
|
8 |
+
switch_to_img2img();
|
9 |
+
setTimeout(function() { gradioApp().getElementById("additional_networks_img2img").scrollIntoView(); }, 100);
|
10 |
+
return args_to_array(arguments);
|
11 |
+
}
|
12 |
+
|
13 |
+
function addnet_switch_to_metadata_editor(){
|
14 |
+
Array.from(gradioApp().querySelector('#tabs').querySelectorAll('button')).filter(e => e.textContent.trim() === "Additional Networks")[0].click();
|
15 |
+
return args_to_array(arguments);
|
16 |
+
}
|
17 |
+
|
18 |
+
function addnet_send_to_metadata_editor() {
|
19 |
+
var module = arguments[0];
|
20 |
+
var model_path = arguments[1];
|
21 |
+
|
22 |
+
if (model_path == "None") {
|
23 |
+
return args_to_array(arguments);
|
24 |
+
}
|
25 |
+
|
26 |
+
console.log(arguments);
|
27 |
+
console.log(model_path);
|
28 |
+
var select = gradioApp().querySelector("#additional_networks_metadata_editor_model > label > select");
|
29 |
+
|
30 |
+
var opt = [...select.options].filter(o => o.text == model_path)[0];
|
31 |
+
if (opt == null) {
|
32 |
+
return;
|
33 |
+
}
|
34 |
+
|
35 |
+
addnet_switch_to_metadata_editor();
|
36 |
+
select.selectedIndex = opt.index;
|
37 |
+
select.dispatchEvent(new Event("change", { bubbles: true }));
|
38 |
+
|
39 |
+
return args_to_array(arguments);
|
40 |
+
}
|
ex/additional-networks/models/lora/.keep
ADDED
File without changes
|
ex/additional-networks/preload.py
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
from modules import paths
|
3 |
+
|
4 |
+
|
5 |
+
def preload(parser):
|
6 |
+
parser.add_argument("--addnet-max-model-count", type=int, help="The maximum number of additional network model can be used.", default=5)
|
ex/additional-networks/scripts/additional_networks.py
ADDED
@@ -0,0 +1,398 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
|
3 |
+
import torch
|
4 |
+
import numpy as np
|
5 |
+
|
6 |
+
import modules.scripts as scripts
|
7 |
+
from modules import shared, script_callbacks
|
8 |
+
import gradio as gr
|
9 |
+
|
10 |
+
import modules.ui
|
11 |
+
from modules.ui_components import ToolButton, FormRow
|
12 |
+
|
13 |
+
from scripts import lora_compvis, model_util, metadata_editor, xyz_grid_support
|
14 |
+
from scripts.model_util import lora_models, MAX_MODEL_COUNT
|
15 |
+
|
16 |
+
|
17 |
+
memo_symbol = "\U0001F4DD" # 📝
|
18 |
+
addnet_paste_params = {"txt2img": [], "img2img": []}
|
19 |
+
|
20 |
+
|
21 |
+
class Script(scripts.Script):
|
22 |
+
def __init__(self) -> None:
|
23 |
+
super().__init__()
|
24 |
+
self.latest_params = [(None, None, None, None)] * MAX_MODEL_COUNT
|
25 |
+
self.latest_networks = []
|
26 |
+
self.latest_model_hash = ""
|
27 |
+
|
28 |
+
def title(self):
|
29 |
+
return "Additional networks for generating"
|
30 |
+
|
31 |
+
def show(self, is_img2img):
|
32 |
+
return scripts.AlwaysVisible
|
33 |
+
|
34 |
+
def ui(self, is_img2img):
|
35 |
+
global addnet_paste_params
|
36 |
+
# NOTE: Changing the contents of `ctrls` means the XY Grid support may need
|
37 |
+
# to be updated, see xyz_grid_support.py
|
38 |
+
ctrls = []
|
39 |
+
weight_sliders = []
|
40 |
+
model_dropdowns = []
|
41 |
+
|
42 |
+
tabname = "txt2img"
|
43 |
+
if is_img2img:
|
44 |
+
tabname = "img2img"
|
45 |
+
|
46 |
+
paste_params = addnet_paste_params[tabname]
|
47 |
+
paste_params.clear()
|
48 |
+
|
49 |
+
self.infotext_fields = []
|
50 |
+
self.paste_field_names = []
|
51 |
+
|
52 |
+
with gr.Group():
|
53 |
+
with gr.Accordion("Additional Networks", open=False):
|
54 |
+
with gr.Row():
|
55 |
+
enabled = gr.Checkbox(label="Enable", value=False)
|
56 |
+
ctrls.append(enabled)
|
57 |
+
self.infotext_fields.append((enabled, "AddNet Enabled"))
|
58 |
+
separate_weights = gr.Checkbox(label="Separate UNet/Text Encoder weights", value=False)
|
59 |
+
ctrls.append(separate_weights)
|
60 |
+
self.infotext_fields.append((separate_weights, "AddNet Separate Weights"))
|
61 |
+
|
62 |
+
for i in range(MAX_MODEL_COUNT):
|
63 |
+
with FormRow(variant="compact"):
|
64 |
+
module = gr.Dropdown(["LoRA"], label=f"Network module {i+1}", value="LoRA")
|
65 |
+
model = gr.Dropdown(list(lora_models.keys()), label=f"Model {i+1}", value="None")
|
66 |
+
with gr.Row(visible=False):
|
67 |
+
model_path = gr.Textbox(value="None", interactive=False, visible=False)
|
68 |
+
model.change(
|
69 |
+
lambda module, model, i=i: model_util.lora_models.get(model, "None"),
|
70 |
+
inputs=[module, model],
|
71 |
+
outputs=[model_path],
|
72 |
+
)
|
73 |
+
|
74 |
+
# Sending from the script UI to the metadata editor has to bypass
|
75 |
+
# gradio since this button will exit the gr.Blocks context by the
|
76 |
+
# time the metadata editor tab is created, so event handlers can't
|
77 |
+
# be registered on it by then.
|
78 |
+
model_info = ToolButton(value=memo_symbol, elem_id=f"additional_networks_send_to_metadata_editor_{i}")
|
79 |
+
model_info.click(fn=None, _js="addnet_send_to_metadata_editor", inputs=[module, model_path], outputs=[])
|
80 |
+
|
81 |
+
module.change(
|
82 |
+
lambda module, model, i=i: xyz_grid_support.update_axis_params(i, module, model),
|
83 |
+
inputs=[module, model],
|
84 |
+
outputs=[],
|
85 |
+
)
|
86 |
+
model.change(
|
87 |
+
lambda module, model, i=i: xyz_grid_support.update_axis_params(i, module, model),
|
88 |
+
inputs=[module, model],
|
89 |
+
outputs=[],
|
90 |
+
)
|
91 |
+
|
92 |
+
# perhaps there is no user to train Text Encoder only, Weight A is U-Net
|
93 |
+
# The name of label will be changed in future (Weight A and B), but UNet and TEnc for now for easy understanding
|
94 |
+
with gr.Column() as col:
|
95 |
+
weight = gr.Slider(label=f"Weight {i+1}", value=1.0, minimum=-1.0, maximum=2.0, step=0.05, visible=True)
|
96 |
+
weight_unet = gr.Slider(
|
97 |
+
label=f"UNet Weight {i+1}", value=1.0, minimum=-1.0, maximum=2.0, step=0.05, visible=False
|
98 |
+
)
|
99 |
+
weight_tenc = gr.Slider(
|
100 |
+
label=f"TEnc Weight {i+1}", value=1.0, minimum=-1.0, maximum=2.0, step=0.05, visible=False
|
101 |
+
)
|
102 |
+
|
103 |
+
weight.change(lambda w: (w, w), inputs=[weight], outputs=[weight_unet, weight_tenc])
|
104 |
+
paste_params.append({"module": module, "model": model})
|
105 |
+
|
106 |
+
ctrls.extend((module, model, weight_unet, weight_tenc))
|
107 |
+
weight_sliders.extend((weight, weight_unet, weight_tenc))
|
108 |
+
model_dropdowns.append(model)
|
109 |
+
|
110 |
+
self.infotext_fields.extend(
|
111 |
+
[
|
112 |
+
(module, f"AddNet Module {i+1}"),
|
113 |
+
(model, f"AddNet Model {i+1}"),
|
114 |
+
(weight, f"AddNet Weight {i+1}"),
|
115 |
+
(weight_unet, f"AddNet Weight A {i+1}"),
|
116 |
+
(weight_tenc, f"AddNet Weight B {i+1}"),
|
117 |
+
]
|
118 |
+
)
|
119 |
+
|
120 |
+
for _, field_name in self.infotext_fields:
|
121 |
+
self.paste_field_names.append(field_name)
|
122 |
+
|
123 |
+
def update_weight_sliders(separate, *sliders):
|
124 |
+
updates = []
|
125 |
+
for w, w_unet, w_tenc in zip(*(iter(sliders),) * 3):
|
126 |
+
if not separate:
|
127 |
+
w_unet = w
|
128 |
+
w_tenc = w
|
129 |
+
updates.append(gr.Slider.update(visible=not separate)) # Combined
|
130 |
+
updates.append(gr.Slider.update(visible=separate, value=w_unet)) # UNet
|
131 |
+
updates.append(gr.Slider.update(visible=separate, value=w_tenc)) # TEnc
|
132 |
+
return updates
|
133 |
+
|
134 |
+
separate_weights.change(update_weight_sliders, inputs=[separate_weights] + weight_sliders, outputs=weight_sliders)
|
135 |
+
|
136 |
+
def refresh_all_models(*dropdowns):
|
137 |
+
model_util.update_models()
|
138 |
+
updates = []
|
139 |
+
for dd in dropdowns:
|
140 |
+
if dd in lora_models:
|
141 |
+
selected = dd
|
142 |
+
else:
|
143 |
+
selected = "None"
|
144 |
+
update = gr.Dropdown.update(value=selected, choices=list(lora_models.keys()))
|
145 |
+
updates.append(update)
|
146 |
+
return updates
|
147 |
+
|
148 |
+
# mask for regions
|
149 |
+
with gr.Accordion("Extra args", open=False):
|
150 |
+
with gr.Row():
|
151 |
+
mask_image = gr.Image(label="mask image:")
|
152 |
+
ctrls.append(mask_image)
|
153 |
+
|
154 |
+
refresh_models = gr.Button(value="Refresh models")
|
155 |
+
refresh_models.click(refresh_all_models, inputs=model_dropdowns, outputs=model_dropdowns)
|
156 |
+
ctrls.append(refresh_models)
|
157 |
+
|
158 |
+
return ctrls
|
159 |
+
|
160 |
+
def set_infotext_fields(self, p, params):
|
161 |
+
for i, t in enumerate(params):
|
162 |
+
module, model, weight_unet, weight_tenc = t
|
163 |
+
if model is None or model == "None" or len(model) == 0 or (weight_unet == 0 and weight_tenc == 0):
|
164 |
+
continue
|
165 |
+
p.extra_generation_params.update(
|
166 |
+
{
|
167 |
+
"AddNet Enabled": True,
|
168 |
+
f"AddNet Module {i+1}": module,
|
169 |
+
f"AddNet Model {i+1}": model,
|
170 |
+
f"AddNet Weight A {i+1}": weight_unet,
|
171 |
+
f"AddNet Weight B {i+1}": weight_tenc,
|
172 |
+
}
|
173 |
+
)
|
174 |
+
|
175 |
+
def restore_networks(self, sd_model):
|
176 |
+
unet = sd_model.model.diffusion_model
|
177 |
+
text_encoder = sd_model.cond_stage_model
|
178 |
+
|
179 |
+
if len(self.latest_networks) > 0:
|
180 |
+
print("restoring last networks")
|
181 |
+
for network, _ in self.latest_networks[::-1]:
|
182 |
+
network.restore(text_encoder, unet)
|
183 |
+
self.latest_networks.clear()
|
184 |
+
|
185 |
+
def process_batch(self, p, *args, **kwargs):
|
186 |
+
unet = p.sd_model.model.diffusion_model
|
187 |
+
text_encoder = p.sd_model.cond_stage_model
|
188 |
+
|
189 |
+
if not args[0]:
|
190 |
+
self.restore_networks(p.sd_model)
|
191 |
+
return
|
192 |
+
|
193 |
+
params = []
|
194 |
+
for i, ctrl in enumerate(args[2:]):
|
195 |
+
if i % 4 == 0:
|
196 |
+
param = [ctrl]
|
197 |
+
else:
|
198 |
+
param.append(ctrl)
|
199 |
+
if i % 4 == 3:
|
200 |
+
params.append(param)
|
201 |
+
|
202 |
+
models_changed = len(self.latest_networks) == 0 # no latest network (cleared by check-off)
|
203 |
+
models_changed = models_changed or self.latest_model_hash != p.sd_model.sd_model_hash
|
204 |
+
if not models_changed:
|
205 |
+
for (l_module, l_model, l_weight_unet, l_weight_tenc), (module, model, weight_unet, weight_tenc) in zip(
|
206 |
+
self.latest_params, params
|
207 |
+
):
|
208 |
+
if l_module != module or l_model != model or l_weight_unet != weight_unet or l_weight_tenc != weight_tenc:
|
209 |
+
models_changed = True
|
210 |
+
break
|
211 |
+
|
212 |
+
if models_changed:
|
213 |
+
self.restore_networks(p.sd_model)
|
214 |
+
self.latest_params = params
|
215 |
+
self.latest_model_hash = p.sd_model.sd_model_hash
|
216 |
+
|
217 |
+
for module, model, weight_unet, weight_tenc in self.latest_params:
|
218 |
+
if model is None or model == "None" or len(model) == 0:
|
219 |
+
continue
|
220 |
+
if weight_unet == 0 and weight_tenc == 0:
|
221 |
+
print(f"ignore because weight is 0: {model}")
|
222 |
+
continue
|
223 |
+
|
224 |
+
model_path = lora_models.get(model, None)
|
225 |
+
if model_path is None:
|
226 |
+
raise RuntimeError(f"model not found: {model}")
|
227 |
+
|
228 |
+
if model_path.startswith('"') and model_path.endswith('"'): # trim '"' at start/end
|
229 |
+
model_path = model_path[1:-1]
|
230 |
+
if not os.path.exists(model_path):
|
231 |
+
print(f"file not found: {model_path}")
|
232 |
+
continue
|
233 |
+
|
234 |
+
print(f"{module} weight_unet: {weight_unet}, weight_tenc: {weight_tenc}, model: {model}")
|
235 |
+
if module == "LoRA":
|
236 |
+
if os.path.splitext(model_path)[1] == ".safetensors":
|
237 |
+
from safetensors.torch import load_file
|
238 |
+
|
239 |
+
du_state_dict = load_file(model_path)
|
240 |
+
else:
|
241 |
+
du_state_dict = torch.load(model_path, map_location="cpu")
|
242 |
+
|
243 |
+
network, info = lora_compvis.create_network_and_apply_compvis(
|
244 |
+
du_state_dict, weight_tenc, weight_unet, text_encoder, unet
|
245 |
+
)
|
246 |
+
# in medvram, device is different for u-net and sd_model, so use sd_model's
|
247 |
+
network.to(p.sd_model.device, dtype=p.sd_model.dtype)
|
248 |
+
|
249 |
+
print(f"LoRA model {model} loaded: {info}")
|
250 |
+
self.latest_networks.append((network, model))
|
251 |
+
if len(self.latest_networks) > 0:
|
252 |
+
print("setting (or sd model) changed. new networks created.")
|
253 |
+
|
254 |
+
# apply mask: currently only top 3 networks are supported
|
255 |
+
if len(self.latest_networks) > 0:
|
256 |
+
mask_image = args[-2]
|
257 |
+
if mask_image is not None:
|
258 |
+
mask_image = mask_image.astype(np.float32) / 255.0
|
259 |
+
print(f"use mask image to control LoRA regions.")
|
260 |
+
for i, (network, model) in enumerate(self.latest_networks[:3]):
|
261 |
+
if not hasattr(network, "set_mask"):
|
262 |
+
continue
|
263 |
+
mask = mask_image[:, :, i] # R,G,B
|
264 |
+
if mask.max() <= 0:
|
265 |
+
continue
|
266 |
+
mask = torch.tensor(mask, dtype=p.sd_model.dtype, device=p.sd_model.device)
|
267 |
+
|
268 |
+
network.set_mask(mask, height=p.height, width=p.width, hr_height=p.hr_upscale_to_y, hr_width=p.hr_upscale_to_x)
|
269 |
+
print(f"apply mask. channel: {i}, model: {model}")
|
270 |
+
else:
|
271 |
+
for network, _ in self.latest_networks:
|
272 |
+
if hasattr(network, "set_mask"):
|
273 |
+
network.set_mask(None)
|
274 |
+
|
275 |
+
self.set_infotext_fields(p, self.latest_params)
|
276 |
+
|
277 |
+
|
278 |
+
def on_script_unloaded():
|
279 |
+
if shared.sd_model:
|
280 |
+
for s in scripts.scripts_txt2img.alwayson_scripts:
|
281 |
+
if isinstance(s, Script):
|
282 |
+
s.restore_networks(shared.sd_model)
|
283 |
+
break
|
284 |
+
|
285 |
+
|
286 |
+
def on_ui_tabs():
|
287 |
+
global addnet_paste_params
|
288 |
+
with gr.Blocks(analytics_enabled=False) as additional_networks_interface:
|
289 |
+
metadata_editor.setup_ui(addnet_paste_params)
|
290 |
+
|
291 |
+
return [(additional_networks_interface, "Additional Networks", "additional_networks")]
|
292 |
+
|
293 |
+
|
294 |
+
def on_ui_settings():
|
295 |
+
section = ("additional_networks", "Additional Networks")
|
296 |
+
shared.opts.add_option(
|
297 |
+
"additional_networks_extra_lora_path",
|
298 |
+
shared.OptionInfo(
|
299 |
+
"",
|
300 |
+
"""Extra paths to scan for LoRA models, comma-separated. Paths containing commas must be enclosed in double quotes. In the path, " (one quote) must be replaced by "" (two quotes).""",
|
301 |
+
section=section,
|
302 |
+
),
|
303 |
+
)
|
304 |
+
shared.opts.add_option(
|
305 |
+
"additional_networks_sort_models_by",
|
306 |
+
shared.OptionInfo(
|
307 |
+
"name",
|
308 |
+
"Sort LoRA models by",
|
309 |
+
gr.Radio,
|
310 |
+
{"choices": ["name", "date", "path name", "rating", "has user metadata"]},
|
311 |
+
section=section,
|
312 |
+
),
|
313 |
+
)
|
314 |
+
shared.opts.add_option(
|
315 |
+
"additional_networks_reverse_sort_order", shared.OptionInfo(False, "Reverse model sort order", section=section)
|
316 |
+
)
|
317 |
+
shared.opts.add_option(
|
318 |
+
"additional_networks_model_name_filter", shared.OptionInfo("", "LoRA model name filter", section=section)
|
319 |
+
)
|
320 |
+
shared.opts.add_option(
|
321 |
+
"additional_networks_xy_grid_model_metadata",
|
322 |
+
shared.OptionInfo(
|
323 |
+
"",
|
324 |
+
'Metadata to show in XY-Grid label for Model axes, comma-separated (example: "ss_learning_rate, ss_num_epochs")',
|
325 |
+
section=section,
|
326 |
+
),
|
327 |
+
)
|
328 |
+
shared.opts.add_option(
|
329 |
+
"additional_networks_hash_thread_count",
|
330 |
+
shared.OptionInfo(1, "# of threads to use for hash calculation (increase if using an SSD)", section=section),
|
331 |
+
)
|
332 |
+
shared.opts.add_option(
|
333 |
+
"additional_networks_back_up_model_when_saving",
|
334 |
+
shared.OptionInfo(True, "Make a backup copy of the model being edited when saving its metadata.", section=section),
|
335 |
+
)
|
336 |
+
shared.opts.add_option(
|
337 |
+
"additional_networks_show_only_safetensors",
|
338 |
+
shared.OptionInfo(False, "Only show .safetensors format models", section=section),
|
339 |
+
)
|
340 |
+
shared.opts.add_option(
|
341 |
+
"additional_networks_show_only_models_with_metadata",
|
342 |
+
shared.OptionInfo(
|
343 |
+
"disabled",
|
344 |
+
"Only show models that have/don't have user-added metadata",
|
345 |
+
gr.Radio,
|
346 |
+
{"choices": ["disabled", "has metadata", "missing metadata"]},
|
347 |
+
section=section,
|
348 |
+
),
|
349 |
+
)
|
350 |
+
shared.opts.add_option(
|
351 |
+
"additional_networks_max_top_tags", shared.OptionInfo(20, "Max number of top tags to show", section=section)
|
352 |
+
)
|
353 |
+
shared.opts.add_option(
|
354 |
+
"additional_networks_max_dataset_folders", shared.OptionInfo(20, "Max number of dataset folders to show", section=section)
|
355 |
+
)
|
356 |
+
|
357 |
+
|
358 |
+
def on_infotext_pasted(infotext, params):
|
359 |
+
if "AddNet Enabled" not in params:
|
360 |
+
params["AddNet Enabled"] = "False"
|
361 |
+
|
362 |
+
# TODO changing "AddNet Separate Weights" does not seem to work
|
363 |
+
if "AddNet Separate Weights" not in params:
|
364 |
+
params["AddNet Separate Weights"] = "False"
|
365 |
+
|
366 |
+
for i in range(MAX_MODEL_COUNT):
|
367 |
+
# Convert combined weight into new format
|
368 |
+
if f"AddNet Weight {i+1}" in params:
|
369 |
+
params[f"AddNet Weight A {i+1}"] = params[f"AddNet Weight {i+1}"]
|
370 |
+
params[f"AddNet Weight B {i+1}"] = params[f"AddNet Weight {i+1}"]
|
371 |
+
|
372 |
+
if f"AddNet Module {i+1}" not in params:
|
373 |
+
params[f"AddNet Module {i+1}"] = "LoRA"
|
374 |
+
if f"AddNet Model {i+1}" not in params:
|
375 |
+
params[f"AddNet Model {i+1}"] = "None"
|
376 |
+
if f"AddNet Weight A {i+1}" not in params:
|
377 |
+
params[f"AddNet Weight A {i+1}"] = "0"
|
378 |
+
if f"AddNet Weight B {i+1}" not in params:
|
379 |
+
params[f"AddNet Weight B {i+1}"] = "0"
|
380 |
+
|
381 |
+
params[f"AddNet Weight {i+1}"] = params[f"AddNet Weight A {i+1}"]
|
382 |
+
|
383 |
+
if params[f"AddNet Weight A {i+1}"] != params[f"AddNet Weight B {i+1}"]:
|
384 |
+
params["AddNet Separate Weights"] = "True"
|
385 |
+
|
386 |
+
# Convert potential legacy name/hash to new format
|
387 |
+
params[f"AddNet Model {i+1}"] = str(model_util.find_closest_lora_model_name(params[f"AddNet Model {i+1}"]))
|
388 |
+
|
389 |
+
xyz_grid_support.update_axis_params(i, params[f"AddNet Module {i+1}"], params[f"AddNet Model {i+1}"])
|
390 |
+
|
391 |
+
|
392 |
+
xyz_grid_support.initialize(Script)
|
393 |
+
|
394 |
+
|
395 |
+
script_callbacks.on_script_unloaded(on_script_unloaded)
|
396 |
+
script_callbacks.on_ui_tabs(on_ui_tabs)
|
397 |
+
script_callbacks.on_ui_settings(on_ui_settings)
|
398 |
+
script_callbacks.on_infotext_pasted(on_infotext_pasted)
|
ex/additional-networks/scripts/lora_compvis.py
ADDED
@@ -0,0 +1,631 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# LoRA network module
|
2 |
+
# reference:
|
3 |
+
# https://github.com/microsoft/LoRA/blob/main/loralib/layers.py
|
4 |
+
# https://github.com/cloneofsimo/lora/blob/master/lora_diffusion/lora.py
|
5 |
+
|
6 |
+
import copy
|
7 |
+
import math
|
8 |
+
import re
|
9 |
+
from typing import NamedTuple
|
10 |
+
import torch
|
11 |
+
|
12 |
+
|
13 |
+
class LoRAInfo(NamedTuple):
|
14 |
+
lora_name: str
|
15 |
+
module_name: str
|
16 |
+
module: torch.nn.Module
|
17 |
+
multiplier: float
|
18 |
+
dim: int
|
19 |
+
alpha: float
|
20 |
+
|
21 |
+
|
22 |
+
class LoRAModule(torch.nn.Module):
|
23 |
+
"""
|
24 |
+
replaces forward method of the original Linear, instead of replacing the original Linear module.
|
25 |
+
"""
|
26 |
+
|
27 |
+
def __init__(self, lora_name, org_module: torch.nn.Module, multiplier=1.0, lora_dim=4, alpha=1):
|
28 |
+
"""if alpha == 0 or None, alpha is rank (no scaling)."""
|
29 |
+
super().__init__()
|
30 |
+
self.lora_name = lora_name
|
31 |
+
self.lora_dim = lora_dim
|
32 |
+
|
33 |
+
if org_module.__class__.__name__ == "Conv2d":
|
34 |
+
in_dim = org_module.in_channels
|
35 |
+
out_dim = org_module.out_channels
|
36 |
+
|
37 |
+
# self.lora_dim = min(self.lora_dim, in_dim, out_dim)
|
38 |
+
# if self.lora_dim != lora_dim:
|
39 |
+
# print(f"{lora_name} dim (rank) is changed to: {self.lora_dim}")
|
40 |
+
|
41 |
+
kernel_size = org_module.kernel_size
|
42 |
+
stride = org_module.stride
|
43 |
+
padding = org_module.padding
|
44 |
+
self.lora_down = torch.nn.Conv2d(in_dim, self.lora_dim, kernel_size, stride, padding, bias=False)
|
45 |
+
self.lora_up = torch.nn.Conv2d(self.lora_dim, out_dim, (1, 1), (1, 1), bias=False)
|
46 |
+
else:
|
47 |
+
in_dim = org_module.in_features
|
48 |
+
out_dim = org_module.out_features
|
49 |
+
self.lora_down = torch.nn.Linear(in_dim, self.lora_dim, bias=False)
|
50 |
+
self.lora_up = torch.nn.Linear(self.lora_dim, out_dim, bias=False)
|
51 |
+
|
52 |
+
if type(alpha) == torch.Tensor:
|
53 |
+
alpha = alpha.detach().float().numpy() # without casting, bf16 causes error
|
54 |
+
alpha = self.lora_dim if alpha is None or alpha == 0 else alpha
|
55 |
+
self.scale = alpha / self.lora_dim
|
56 |
+
self.register_buffer("alpha", torch.tensor(alpha)) # 定数として扱える
|
57 |
+
|
58 |
+
# same as microsoft's
|
59 |
+
torch.nn.init.kaiming_uniform_(self.lora_down.weight, a=math.sqrt(5))
|
60 |
+
torch.nn.init.zeros_(self.lora_up.weight)
|
61 |
+
|
62 |
+
self.multiplier = multiplier
|
63 |
+
self.org_forward = org_module.forward
|
64 |
+
self.org_module = org_module # remove in applying
|
65 |
+
self.mask_dic = None
|
66 |
+
self.mask = None
|
67 |
+
self.mask_area = -1
|
68 |
+
|
69 |
+
def apply_to(self):
|
70 |
+
self.org_forward = self.org_module.forward
|
71 |
+
self.org_module.forward = self.forward
|
72 |
+
del self.org_module
|
73 |
+
|
74 |
+
def set_mask_dic(self, mask_dic):
|
75 |
+
# called before every generation
|
76 |
+
|
77 |
+
# check this module is related to h,w (not context and time emb)
|
78 |
+
if "attn2_to_k" in self.lora_name or "attn2_to_v" in self.lora_name or "emb_layers" in self.lora_name:
|
79 |
+
# print(f"LoRA for context or time emb: {self.lora_name}")
|
80 |
+
self.mask_dic = None
|
81 |
+
else:
|
82 |
+
self.mask_dic = mask_dic
|
83 |
+
|
84 |
+
self.mask = None
|
85 |
+
|
86 |
+
def forward(self, x):
|
87 |
+
"""
|
88 |
+
may be cascaded.
|
89 |
+
"""
|
90 |
+
if self.mask_dic is None:
|
91 |
+
return self.org_forward(x) + self.lora_up(self.lora_down(x)) * self.multiplier * self.scale
|
92 |
+
|
93 |
+
# regional LoRA
|
94 |
+
|
95 |
+
# calculate lora and get size
|
96 |
+
lx = self.lora_up(self.lora_down(x))
|
97 |
+
|
98 |
+
if len(lx.size()) == 4: # b,c,h,w
|
99 |
+
area = lx.size()[2] * lx.size()[3]
|
100 |
+
else:
|
101 |
+
area = lx.size()[1] # b,seq,dim
|
102 |
+
|
103 |
+
if self.mask is None or self.mask_area != area:
|
104 |
+
# get mask
|
105 |
+
# print(self.lora_name, x.size(), lx.size(), area)
|
106 |
+
mask = self.mask_dic[area]
|
107 |
+
if len(lx.size()) == 3:
|
108 |
+
mask = torch.reshape(mask, (1, -1, 1))
|
109 |
+
self.mask = mask
|
110 |
+
self.mask_area = area
|
111 |
+
|
112 |
+
return self.org_forward(x) + lx * self.multiplier * self.scale * self.mask
|
113 |
+
|
114 |
+
|
115 |
+
def create_network_and_apply_compvis(du_state_dict, multiplier_tenc, multiplier_unet, text_encoder, unet, **kwargs):
|
116 |
+
# get device and dtype from unet
|
117 |
+
for module in unet.modules():
|
118 |
+
if module.__class__.__name__ == "Linear":
|
119 |
+
param: torch.nn.Parameter = module.weight
|
120 |
+
# device = param.device
|
121 |
+
dtype = param.dtype
|
122 |
+
break
|
123 |
+
|
124 |
+
# get dims (rank) and alpha from state dict
|
125 |
+
modules_dim = {}
|
126 |
+
modules_alpha = {}
|
127 |
+
for key, value in du_state_dict.items():
|
128 |
+
if "." not in key:
|
129 |
+
continue
|
130 |
+
|
131 |
+
lora_name = key.split(".")[0]
|
132 |
+
if "alpha" in key:
|
133 |
+
modules_alpha[lora_name] = float(value.detach().to(torch.float).cpu().numpy())
|
134 |
+
elif "lora_down" in key:
|
135 |
+
dim = value.size()[0]
|
136 |
+
modules_dim[lora_name] = dim
|
137 |
+
|
138 |
+
# support old LoRA without alpha
|
139 |
+
for key in modules_dim.keys():
|
140 |
+
if key not in modules_alpha:
|
141 |
+
modules_alpha[key] = modules_dim[key]
|
142 |
+
|
143 |
+
print(
|
144 |
+
f"dimension: {set(modules_dim.values())}, alpha: {set(modules_alpha.values())}, multiplier_unet: {multiplier_unet}, multiplier_tenc: {multiplier_tenc}"
|
145 |
+
)
|
146 |
+
|
147 |
+
# if network_dim is None:
|
148 |
+
# print(f"The selected model is not LoRA or not trained by `sd-scripts`?")
|
149 |
+
# network_dim = 4
|
150 |
+
# network_alpha = 1
|
151 |
+
|
152 |
+
# create, apply and load weights
|
153 |
+
network = LoRANetworkCompvis(text_encoder, unet, multiplier_tenc, multiplier_unet, modules_dim, modules_alpha)
|
154 |
+
state_dict = network.apply_lora_modules(du_state_dict) # some weights are applied to text encoder
|
155 |
+
network.to(dtype) # with this, if error comes from next line, the model will be used
|
156 |
+
info = network.load_state_dict(state_dict, strict=False)
|
157 |
+
|
158 |
+
# remove redundant warnings
|
159 |
+
if len(info.missing_keys) > 4:
|
160 |
+
missing_keys = []
|
161 |
+
alpha_count = 0
|
162 |
+
for key in info.missing_keys:
|
163 |
+
if "alpha" not in key:
|
164 |
+
missing_keys.append(key)
|
165 |
+
else:
|
166 |
+
if alpha_count == 0:
|
167 |
+
missing_keys.append(key)
|
168 |
+
alpha_count += 1
|
169 |
+
if alpha_count > 1:
|
170 |
+
missing_keys.append(
|
171 |
+
f"... and {alpha_count-1} alphas. The model doesn't have alpha, use dim (rannk) as alpha. You can ignore this message."
|
172 |
+
)
|
173 |
+
|
174 |
+
info = torch.nn.modules.module._IncompatibleKeys(missing_keys, info.unexpected_keys)
|
175 |
+
|
176 |
+
return network, info
|
177 |
+
|
178 |
+
|
179 |
+
class LoRANetworkCompvis(torch.nn.Module):
|
180 |
+
# UNET_TARGET_REPLACE_MODULE = ["Transformer2DModel", "Attention"]
|
181 |
+
# TEXT_ENCODER_TARGET_REPLACE_MODULE = ["CLIPAttention", "CLIPMLP"]
|
182 |
+
UNET_TARGET_REPLACE_MODULE = ["SpatialTransformer", "ResBlock", "Downsample", "Upsample"] # , "Attention"]
|
183 |
+
TEXT_ENCODER_TARGET_REPLACE_MODULE = ["ResidualAttentionBlock", "CLIPAttention", "CLIPMLP"]
|
184 |
+
|
185 |
+
LORA_PREFIX_UNET = "lora_unet"
|
186 |
+
LORA_PREFIX_TEXT_ENCODER = "lora_te"
|
187 |
+
|
188 |
+
@classmethod
|
189 |
+
def convert_diffusers_name_to_compvis(cls, v2, du_name):
|
190 |
+
"""
|
191 |
+
convert diffusers's LoRA name to CompVis
|
192 |
+
"""
|
193 |
+
cv_name = None
|
194 |
+
if "lora_unet_" in du_name:
|
195 |
+
m = re.search(r"_down_blocks_(\d+)_attentions_(\d+)_(.+)", du_name)
|
196 |
+
if m:
|
197 |
+
du_block_index = int(m.group(1))
|
198 |
+
du_attn_index = int(m.group(2))
|
199 |
+
du_suffix = m.group(3)
|
200 |
+
|
201 |
+
cv_index = 1 + du_block_index * 3 + du_attn_index # 1,2, 4,5, 7,8
|
202 |
+
cv_name = f"lora_unet_input_blocks_{cv_index}_1_{du_suffix}"
|
203 |
+
return cv_name
|
204 |
+
|
205 |
+
m = re.search(r"_mid_block_attentions_(\d+)_(.+)", du_name)
|
206 |
+
if m:
|
207 |
+
du_suffix = m.group(2)
|
208 |
+
cv_name = f"lora_unet_middle_block_1_{du_suffix}"
|
209 |
+
return cv_name
|
210 |
+
|
211 |
+
m = re.search(r"_up_blocks_(\d+)_attentions_(\d+)_(.+)", du_name)
|
212 |
+
if m:
|
213 |
+
du_block_index = int(m.group(1))
|
214 |
+
du_attn_index = int(m.group(2))
|
215 |
+
du_suffix = m.group(3)
|
216 |
+
|
217 |
+
cv_index = du_block_index * 3 + du_attn_index # 3,4,5, 6,7,8, 9,10,11
|
218 |
+
cv_name = f"lora_unet_output_blocks_{cv_index}_1_{du_suffix}"
|
219 |
+
return cv_name
|
220 |
+
|
221 |
+
m = re.search(r"_down_blocks_(\d+)_resnets_(\d+)_(.+)", du_name)
|
222 |
+
if m:
|
223 |
+
du_block_index = int(m.group(1))
|
224 |
+
du_res_index = int(m.group(2))
|
225 |
+
du_suffix = m.group(3)
|
226 |
+
cv_suffix = {
|
227 |
+
"conv1": "in_layers_2",
|
228 |
+
"conv2": "out_layers_3",
|
229 |
+
"time_emb_proj": "emb_layers_1",
|
230 |
+
"conv_shortcut": "skip_connection",
|
231 |
+
}[du_suffix]
|
232 |
+
|
233 |
+
cv_index = 1 + du_block_index * 3 + du_res_index # 1,2, 4,5, 7,8
|
234 |
+
cv_name = f"lora_unet_input_blocks_{cv_index}_0_{cv_suffix}"
|
235 |
+
return cv_name
|
236 |
+
|
237 |
+
m = re.search(r"_down_blocks_(\d+)_downsamplers_0_conv", du_name)
|
238 |
+
if m:
|
239 |
+
block_index = int(m.group(1))
|
240 |
+
cv_index = 3 + block_index * 3
|
241 |
+
cv_name = f"lora_unet_input_blocks_{cv_index}_0_op"
|
242 |
+
return cv_name
|
243 |
+
|
244 |
+
m = re.search(r"_mid_block_resnets_(\d+)_(.+)", du_name)
|
245 |
+
if m:
|
246 |
+
index = int(m.group(1))
|
247 |
+
du_suffix = m.group(2)
|
248 |
+
cv_suffix = {
|
249 |
+
"conv1": "in_layers_2",
|
250 |
+
"conv2": "out_layers_3",
|
251 |
+
"time_emb_proj": "emb_layers_1",
|
252 |
+
"conv_shortcut": "skip_connection",
|
253 |
+
}[du_suffix]
|
254 |
+
cv_name = f"lora_unet_middle_block_{index*2}_{cv_suffix}"
|
255 |
+
return cv_name
|
256 |
+
|
257 |
+
m = re.search(r"_up_blocks_(\d+)_resnets_(\d+)_(.+)", du_name)
|
258 |
+
if m:
|
259 |
+
du_block_index = int(m.group(1))
|
260 |
+
du_res_index = int(m.group(2))
|
261 |
+
du_suffix = m.group(3)
|
262 |
+
cv_suffix = {
|
263 |
+
"conv1": "in_layers_2",
|
264 |
+
"conv2": "out_layers_3",
|
265 |
+
"time_emb_proj": "emb_layers_1",
|
266 |
+
"conv_shortcut": "skip_connection",
|
267 |
+
}[du_suffix]
|
268 |
+
|
269 |
+
cv_index = du_block_index * 3 + du_res_index # 1,2, 4,5, 7,8
|
270 |
+
cv_name = f"lora_unet_output_blocks_{cv_index}_0_{cv_suffix}"
|
271 |
+
return cv_name
|
272 |
+
|
273 |
+
m = re.search(r"_up_blocks_(\d+)_upsamplers_0_conv", du_name)
|
274 |
+
if m:
|
275 |
+
block_index = int(m.group(1))
|
276 |
+
cv_index = block_index * 3 + 2
|
277 |
+
cv_name = f"lora_unet_output_blocks_{cv_index}_{bool(block_index)+1}_conv"
|
278 |
+
return cv_name
|
279 |
+
|
280 |
+
elif "lora_te_" in du_name:
|
281 |
+
m = re.search(r"_model_encoder_layers_(\d+)_(.+)", du_name)
|
282 |
+
if m:
|
283 |
+
du_block_index = int(m.group(1))
|
284 |
+
du_suffix = m.group(2)
|
285 |
+
|
286 |
+
cv_index = du_block_index
|
287 |
+
if v2:
|
288 |
+
if "mlp_fc1" in du_suffix:
|
289 |
+
cv_name = (
|
290 |
+
f"lora_te_wrapped_model_transformer_resblocks_{cv_index}_{du_suffix.replace('mlp_fc1', 'mlp_c_fc')}"
|
291 |
+
)
|
292 |
+
elif "mlp_fc2" in du_suffix:
|
293 |
+
cv_name = (
|
294 |
+
f"lora_te_wrapped_model_transformer_resblocks_{cv_index}_{du_suffix.replace('mlp_fc2', 'mlp_c_proj')}"
|
295 |
+
)
|
296 |
+
elif "self_attn":
|
297 |
+
# handled later
|
298 |
+
cv_name = f"lora_te_wrapped_model_transformer_resblocks_{cv_index}_{du_suffix.replace('self_attn', 'attn')}"
|
299 |
+
else:
|
300 |
+
cv_name = f"lora_te_wrapped_transformer_text_model_encoder_layers_{cv_index}_{du_suffix}"
|
301 |
+
|
302 |
+
assert cv_name is not None, f"conversion failed: {du_name}. the model may not be trained by `sd-scripts`."
|
303 |
+
return cv_name
|
304 |
+
|
305 |
+
@classmethod
|
306 |
+
def convert_state_dict_name_to_compvis(cls, v2, state_dict):
|
307 |
+
"""
|
308 |
+
convert keys in state dict to load it by load_state_dict
|
309 |
+
"""
|
310 |
+
new_sd = {}
|
311 |
+
for key, value in state_dict.items():
|
312 |
+
tokens = key.split(".")
|
313 |
+
compvis_name = LoRANetworkCompvis.convert_diffusers_name_to_compvis(v2, tokens[0])
|
314 |
+
new_key = compvis_name + "." + ".".join(tokens[1:])
|
315 |
+
|
316 |
+
new_sd[new_key] = value
|
317 |
+
|
318 |
+
return new_sd
|
319 |
+
|
320 |
+
def __init__(self, text_encoder, unet, multiplier_tenc=1.0, multiplier_unet=1.0, modules_dim=None, modules_alpha=None) -> None:
|
321 |
+
super().__init__()
|
322 |
+
self.multiplier_unet = multiplier_unet
|
323 |
+
self.multiplier_tenc = multiplier_tenc
|
324 |
+
self.latest_mask_info = None
|
325 |
+
|
326 |
+
# check v1 or v2
|
327 |
+
self.v2 = False
|
328 |
+
for _, module in text_encoder.named_modules():
|
329 |
+
for _, child_module in module.named_modules():
|
330 |
+
if child_module.__class__.__name__ == "MultiheadAttention":
|
331 |
+
self.v2 = True
|
332 |
+
break
|
333 |
+
if self.v2:
|
334 |
+
break
|
335 |
+
|
336 |
+
# convert lora name to CompVis and get dim and alpha
|
337 |
+
comp_vis_loras_dim_alpha = {}
|
338 |
+
for du_lora_name in modules_dim.keys():
|
339 |
+
dim = modules_dim[du_lora_name]
|
340 |
+
alpha = modules_alpha[du_lora_name]
|
341 |
+
comp_vis_lora_name = LoRANetworkCompvis.convert_diffusers_name_to_compvis(self.v2, du_lora_name)
|
342 |
+
comp_vis_loras_dim_alpha[comp_vis_lora_name] = (dim, alpha)
|
343 |
+
|
344 |
+
# create module instances
|
345 |
+
def create_modules(prefix, root_module: torch.nn.Module, target_replace_modules, multiplier):
|
346 |
+
loras = []
|
347 |
+
replaced_modules = []
|
348 |
+
for name, module in root_module.named_modules():
|
349 |
+
if module.__class__.__name__ in target_replace_modules:
|
350 |
+
for child_name, child_module in module.named_modules():
|
351 |
+
# enumerate all Linear and Conv2d
|
352 |
+
if child_module.__class__.__name__ == "Linear" or child_module.__class__.__name__ == "Conv2d":
|
353 |
+
lora_name = prefix + "." + name + "." + child_name
|
354 |
+
lora_name = lora_name.replace(".", "_")
|
355 |
+
if "_resblocks_23_" in lora_name: # ignore last block in StabilityAi Text Encoder
|
356 |
+
break
|
357 |
+
if lora_name not in comp_vis_loras_dim_alpha:
|
358 |
+
continue
|
359 |
+
|
360 |
+
dim, alpha = comp_vis_loras_dim_alpha[lora_name]
|
361 |
+
lora = LoRAModule(lora_name, child_module, multiplier, dim, alpha)
|
362 |
+
loras.append(lora)
|
363 |
+
|
364 |
+
replaced_modules.append(child_module)
|
365 |
+
elif child_module.__class__.__name__ == "MultiheadAttention":
|
366 |
+
# make four modules: not replacing forward method but merge weights later
|
367 |
+
for suffix in ["q_proj", "k_proj", "v_proj", "out_proj"]:
|
368 |
+
module_name = prefix + "." + name + "." + child_name # ~.attn
|
369 |
+
module_name = module_name.replace(".", "_")
|
370 |
+
if "_resblocks_23_" in module_name: # ignore last block in StabilityAi Text Encoder
|
371 |
+
break
|
372 |
+
|
373 |
+
lora_name = module_name + "_" + suffix
|
374 |
+
if lora_name not in comp_vis_loras_dim_alpha:
|
375 |
+
continue
|
376 |
+
dim, alpha = comp_vis_loras_dim_alpha[lora_name]
|
377 |
+
lora_info = LoRAInfo(lora_name, module_name, child_module, multiplier, dim, alpha)
|
378 |
+
loras.append(lora_info)
|
379 |
+
|
380 |
+
replaced_modules.append(child_module)
|
381 |
+
return loras, replaced_modules
|
382 |
+
|
383 |
+
self.text_encoder_loras, te_rep_modules = create_modules(
|
384 |
+
LoRANetworkCompvis.LORA_PREFIX_TEXT_ENCODER,
|
385 |
+
text_encoder,
|
386 |
+
LoRANetworkCompvis.TEXT_ENCODER_TARGET_REPLACE_MODULE,
|
387 |
+
self.multiplier_tenc,
|
388 |
+
)
|
389 |
+
print(f"create LoRA for Text Encoder: {len(self.text_encoder_loras)} modules.")
|
390 |
+
|
391 |
+
self.unet_loras, unet_rep_modules = create_modules(
|
392 |
+
LoRANetworkCompvis.LORA_PREFIX_UNET, unet, LoRANetworkCompvis.UNET_TARGET_REPLACE_MODULE, self.multiplier_unet
|
393 |
+
)
|
394 |
+
print(f"create LoRA for U-Net: {len(self.unet_loras)} modules.")
|
395 |
+
|
396 |
+
# make backup of original forward/weights, if multiple modules are applied, do in 1st module only
|
397 |
+
backed_up = False # messaging purpose only
|
398 |
+
for rep_module in te_rep_modules + unet_rep_modules:
|
399 |
+
if (
|
400 |
+
rep_module.__class__.__name__ == "MultiheadAttention"
|
401 |
+
): # multiple MHA modules are in list, prevent to backed up forward
|
402 |
+
if not hasattr(rep_module, "_lora_org_weights"):
|
403 |
+
# avoid updating of original weights. state_dict is reference to original weights
|
404 |
+
rep_module._lora_org_weights = copy.deepcopy(rep_module.state_dict())
|
405 |
+
backed_up = True
|
406 |
+
elif not hasattr(rep_module, "_lora_org_forward"):
|
407 |
+
rep_module._lora_org_forward = rep_module.forward
|
408 |
+
backed_up = True
|
409 |
+
if backed_up:
|
410 |
+
print("original forward/weights is backed up.")
|
411 |
+
|
412 |
+
# assertion
|
413 |
+
names = set()
|
414 |
+
for lora in self.text_encoder_loras + self.unet_loras:
|
415 |
+
assert lora.lora_name not in names, f"duplicated lora name: {lora.lora_name}"
|
416 |
+
names.add(lora.lora_name)
|
417 |
+
|
418 |
+
def restore(self, text_encoder, unet):
|
419 |
+
# restore forward/weights from property for all modules
|
420 |
+
restored = False # messaging purpose only
|
421 |
+
modules = []
|
422 |
+
modules.extend(text_encoder.modules())
|
423 |
+
modules.extend(unet.modules())
|
424 |
+
for module in modules:
|
425 |
+
if hasattr(module, "_lora_org_forward"):
|
426 |
+
module.forward = module._lora_org_forward
|
427 |
+
del module._lora_org_forward
|
428 |
+
restored = True
|
429 |
+
if hasattr(
|
430 |
+
module, "_lora_org_weights"
|
431 |
+
): # module doesn't have forward and weights at same time currently, but supports it for future changing
|
432 |
+
module.load_state_dict(module._lora_org_weights)
|
433 |
+
del module._lora_org_weights
|
434 |
+
restored = True
|
435 |
+
|
436 |
+
if restored:
|
437 |
+
print("original forward/weights is restored.")
|
438 |
+
|
439 |
+
def apply_lora_modules(self, du_state_dict):
|
440 |
+
# conversion 1st step: convert names in state_dict
|
441 |
+
state_dict = LoRANetworkCompvis.convert_state_dict_name_to_compvis(self.v2, du_state_dict)
|
442 |
+
|
443 |
+
# check state_dict has text_encoder or unet
|
444 |
+
weights_has_text_encoder = weights_has_unet = False
|
445 |
+
for key in state_dict.keys():
|
446 |
+
if key.startswith(LoRANetworkCompvis.LORA_PREFIX_TEXT_ENCODER):
|
447 |
+
weights_has_text_encoder = True
|
448 |
+
elif key.startswith(LoRANetworkCompvis.LORA_PREFIX_UNET):
|
449 |
+
weights_has_unet = True
|
450 |
+
if weights_has_text_encoder and weights_has_unet:
|
451 |
+
break
|
452 |
+
|
453 |
+
apply_text_encoder = weights_has_text_encoder
|
454 |
+
apply_unet = weights_has_unet
|
455 |
+
|
456 |
+
if apply_text_encoder:
|
457 |
+
print("enable LoRA for text encoder")
|
458 |
+
else:
|
459 |
+
self.text_encoder_loras = []
|
460 |
+
|
461 |
+
if apply_unet:
|
462 |
+
print("enable LoRA for U-Net")
|
463 |
+
else:
|
464 |
+
self.unet_loras = []
|
465 |
+
|
466 |
+
# add modules to network: this makes state_dict can be got from LoRANetwork
|
467 |
+
mha_loras = {}
|
468 |
+
for lora in self.text_encoder_loras + self.unet_loras:
|
469 |
+
if type(lora) == LoRAModule:
|
470 |
+
lora.apply_to() # ensure remove reference to original Linear: reference makes key of state_dict
|
471 |
+
self.add_module(lora.lora_name, lora)
|
472 |
+
else:
|
473 |
+
# SD2.x MultiheadAttention merge weights to MHA weights
|
474 |
+
lora_info: LoRAInfo = lora
|
475 |
+
if lora_info.module_name not in mha_loras:
|
476 |
+
mha_loras[lora_info.module_name] = {}
|
477 |
+
|
478 |
+
lora_dic = mha_loras[lora_info.module_name]
|
479 |
+
lora_dic[lora_info.lora_name] = lora_info
|
480 |
+
if len(lora_dic) == 4:
|
481 |
+
# calculate and apply
|
482 |
+
module = lora_info.module
|
483 |
+
module_name = lora_info.module_name
|
484 |
+
w_q_dw = state_dict.get(module_name + "_q_proj.lora_down.weight")
|
485 |
+
if w_q_dw is not None: # corresponding LoRA module exists
|
486 |
+
w_q_up = state_dict[module_name + "_q_proj.lora_up.weight"]
|
487 |
+
w_k_dw = state_dict[module_name + "_k_proj.lora_down.weight"]
|
488 |
+
w_k_up = state_dict[module_name + "_k_proj.lora_up.weight"]
|
489 |
+
w_v_dw = state_dict[module_name + "_v_proj.lora_down.weight"]
|
490 |
+
w_v_up = state_dict[module_name + "_v_proj.lora_up.weight"]
|
491 |
+
w_out_dw = state_dict[module_name + "_out_proj.lora_down.weight"]
|
492 |
+
w_out_up = state_dict[module_name + "_out_proj.lora_up.weight"]
|
493 |
+
q_lora_info = lora_dic[module_name + "_q_proj"]
|
494 |
+
k_lora_info = lora_dic[module_name + "_k_proj"]
|
495 |
+
v_lora_info = lora_dic[module_name + "_v_proj"]
|
496 |
+
out_lora_info = lora_dic[module_name + "_out_proj"]
|
497 |
+
|
498 |
+
sd = module.state_dict()
|
499 |
+
qkv_weight = sd["in_proj_weight"]
|
500 |
+
out_weight = sd["out_proj.weight"]
|
501 |
+
dev = qkv_weight.device
|
502 |
+
|
503 |
+
def merge_weights(l_info, weight, up_weight, down_weight):
|
504 |
+
# calculate in float
|
505 |
+
scale = l_info.alpha / l_info.dim
|
506 |
+
dtype = weight.dtype
|
507 |
+
weight = (
|
508 |
+
weight.float()
|
509 |
+
+ l_info.multiplier
|
510 |
+
* (up_weight.to(dev, dtype=torch.float) @ down_weight.to(dev, dtype=torch.float))
|
511 |
+
* scale
|
512 |
+
)
|
513 |
+
weight = weight.to(dtype)
|
514 |
+
return weight
|
515 |
+
|
516 |
+
q_weight, k_weight, v_weight = torch.chunk(qkv_weight, 3)
|
517 |
+
if q_weight.size()[1] == w_q_up.size()[0]:
|
518 |
+
q_weight = merge_weights(q_lora_info, q_weight, w_q_up, w_q_dw)
|
519 |
+
k_weight = merge_weights(k_lora_info, k_weight, w_k_up, w_k_dw)
|
520 |
+
v_weight = merge_weights(v_lora_info, v_weight, w_v_up, w_v_dw)
|
521 |
+
qkv_weight = torch.cat([q_weight, k_weight, v_weight])
|
522 |
+
|
523 |
+
out_weight = merge_weights(out_lora_info, out_weight, w_out_up, w_out_dw)
|
524 |
+
|
525 |
+
sd["in_proj_weight"] = qkv_weight.to(dev)
|
526 |
+
sd["out_proj.weight"] = out_weight.to(dev)
|
527 |
+
|
528 |
+
lora_info.module.load_state_dict(sd)
|
529 |
+
else:
|
530 |
+
# different dim, version mismatch
|
531 |
+
print(f"shape of weight is different: {module_name}. SD version may be different")
|
532 |
+
|
533 |
+
for t in ["q", "k", "v", "out"]:
|
534 |
+
del state_dict[f"{module_name}_{t}_proj.lora_down.weight"]
|
535 |
+
del state_dict[f"{module_name}_{t}_proj.lora_up.weight"]
|
536 |
+
alpha_key = f"{module_name}_{t}_proj.alpha"
|
537 |
+
if alpha_key in state_dict:
|
538 |
+
del state_dict[alpha_key]
|
539 |
+
else:
|
540 |
+
# corresponding weight not exists: version mismatch
|
541 |
+
pass
|
542 |
+
|
543 |
+
# conversion 2nd step: convert weight's shape (and handle wrapped)
|
544 |
+
state_dict = self.convert_state_dict_shape_to_compvis(state_dict)
|
545 |
+
|
546 |
+
return state_dict
|
547 |
+
|
548 |
+
def convert_state_dict_shape_to_compvis(self, state_dict):
|
549 |
+
# shape conversion
|
550 |
+
current_sd = self.state_dict() # to get target shape
|
551 |
+
wrapped = False
|
552 |
+
count = 0
|
553 |
+
for key in list(state_dict.keys()):
|
554 |
+
if key not in current_sd:
|
555 |
+
continue # might be error or another version
|
556 |
+
if "wrapped" in key:
|
557 |
+
wrapped = True
|
558 |
+
|
559 |
+
value: torch.Tensor = state_dict[key]
|
560 |
+
if value.size() != current_sd[key].size():
|
561 |
+
# print(f"convert weights shape: {key}, from: {value.size()}, {len(value.size())}")
|
562 |
+
count += 1
|
563 |
+
if len(value.size()) == 4:
|
564 |
+
value = value.squeeze(3).squeeze(2)
|
565 |
+
else:
|
566 |
+
value = value.unsqueeze(2).unsqueeze(3)
|
567 |
+
state_dict[key] = value
|
568 |
+
if tuple(value.size()) != tuple(current_sd[key].size()):
|
569 |
+
print(
|
570 |
+
f"weight's shape is different: {key} expected {current_sd[key].size()} found {value.size()}. SD version may be different"
|
571 |
+
)
|
572 |
+
del state_dict[key]
|
573 |
+
print(f"shapes for {count} weights are converted.")
|
574 |
+
|
575 |
+
# convert wrapped
|
576 |
+
if not wrapped:
|
577 |
+
print("remove 'wrapped' from keys")
|
578 |
+
for key in list(state_dict.keys()):
|
579 |
+
if "_wrapped_" in key:
|
580 |
+
new_key = key.replace("_wrapped_", "_")
|
581 |
+
state_dict[new_key] = state_dict[key]
|
582 |
+
del state_dict[key]
|
583 |
+
|
584 |
+
return state_dict
|
585 |
+
|
586 |
+
def set_mask(self, mask, height=None, width=None, hr_height=None, hr_width=None):
|
587 |
+
if mask is None:
|
588 |
+
# clear latest mask
|
589 |
+
# print("clear mask")
|
590 |
+
self.latest_mask_info = None
|
591 |
+
for lora in self.unet_loras:
|
592 |
+
lora.set_mask_dic(None)
|
593 |
+
return
|
594 |
+
|
595 |
+
# check mask image and h/w are same
|
596 |
+
if (
|
597 |
+
self.latest_mask_info is not None
|
598 |
+
and torch.equal(mask, self.latest_mask_info[0])
|
599 |
+
and (height, width, hr_height, hr_width) == self.latest_mask_info[1:]
|
600 |
+
):
|
601 |
+
# print("mask not changed")
|
602 |
+
return
|
603 |
+
|
604 |
+
self.latest_mask_info = (mask, height, width, hr_height, hr_width)
|
605 |
+
|
606 |
+
org_dtype = mask.dtype
|
607 |
+
if mask.dtype == torch.bfloat16:
|
608 |
+
mask = mask.to(torch.float)
|
609 |
+
|
610 |
+
mask_dic = {}
|
611 |
+
mask = mask.unsqueeze(0).unsqueeze(1) # b(1),c(1),h,w
|
612 |
+
|
613 |
+
def resize_add(mh, mw):
|
614 |
+
# print(mh, mw, mh * mw)
|
615 |
+
m = torch.nn.functional.interpolate(mask, (mh, mw), mode="bilinear") # doesn't work in bf16
|
616 |
+
m = m.to(org_dtype)
|
617 |
+
mask_dic[mh * mw] = m
|
618 |
+
|
619 |
+
for h, w in [(height, width), (hr_height, hr_width)]:
|
620 |
+
h = h // 8
|
621 |
+
w = w // 8
|
622 |
+
for i in range(4):
|
623 |
+
resize_add(h, w)
|
624 |
+
if h % 2 == 1 or w % 2 == 1: # add extra shape if h/w is not divisible by 2
|
625 |
+
resize_add(h + h % 2, w + w % 2)
|
626 |
+
h = (h + 1) // 2
|
627 |
+
w = (w + 1) // 2
|
628 |
+
|
629 |
+
for lora in self.unet_loras:
|
630 |
+
lora.set_mask_dic(mask_dic)
|
631 |
+
return
|
ex/additional-networks/scripts/metadata_editor.py
ADDED
@@ -0,0 +1,484 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import json
|
3 |
+
import sys
|
4 |
+
import io
|
5 |
+
import base64
|
6 |
+
import platform
|
7 |
+
import subprocess as sp
|
8 |
+
from PIL import PngImagePlugin, Image
|
9 |
+
|
10 |
+
from modules import shared
|
11 |
+
import gradio as gr
|
12 |
+
|
13 |
+
import modules.ui
|
14 |
+
from modules.ui_components import ToolButton
|
15 |
+
import modules.extras
|
16 |
+
import modules.generation_parameters_copypaste as parameters_copypaste
|
17 |
+
|
18 |
+
from scripts import safetensors_hack, model_util
|
19 |
+
from scripts.model_util import MAX_MODEL_COUNT
|
20 |
+
|
21 |
+
|
22 |
+
folder_symbol = '\U0001f4c2' # 📂
|
23 |
+
keycap_symbols = [
|
24 |
+
'\u0031\ufe0f\u20e3', # 1️⃣
|
25 |
+
'\u0032\ufe0f\u20e3', # 2️⃣
|
26 |
+
'\u0033\ufe0f\u20e3', # 3️⃣
|
27 |
+
'\u0034\ufe0f\u20e3', # 4️⃣
|
28 |
+
'\u0035\ufe0f\u20e3', # 5️⃣
|
29 |
+
'\u0036\ufe0f\u20e3', # 6️⃣
|
30 |
+
'\u0037\ufe0f\u20e3', # 7️⃣
|
31 |
+
'\u0038\ufe0f\u20e3', # 8️
|
32 |
+
'\u0039\ufe0f\u20e3', # 9️
|
33 |
+
'\u1f51f' # 🔟
|
34 |
+
]
|
35 |
+
|
36 |
+
|
37 |
+
def write_webui_model_preview_image(model_path, image):
|
38 |
+
basename, ext = os.path.splitext(model_path)
|
39 |
+
preview_path = f"{basename}.png"
|
40 |
+
|
41 |
+
# Copy any text-only metadata
|
42 |
+
use_metadata = False
|
43 |
+
metadata = PngImagePlugin.PngInfo()
|
44 |
+
for key, value in image.info.items():
|
45 |
+
if isinstance(key, str) and isinstance(value, str):
|
46 |
+
metadata.add_text(key, value)
|
47 |
+
use_metadata = True
|
48 |
+
|
49 |
+
image.save(preview_path, "PNG", pnginfo=(metadata if use_metadata else None))
|
50 |
+
|
51 |
+
|
52 |
+
def delete_webui_model_preview_image(model_path):
|
53 |
+
basename, ext = os.path.splitext(model_path)
|
54 |
+
preview_paths = [f"{basename}.preview.png", f"{basename}.png"]
|
55 |
+
|
56 |
+
for preview_path in preview_paths:
|
57 |
+
if os.path.isfile(preview_path):
|
58 |
+
os.unlink(preview_path)
|
59 |
+
|
60 |
+
|
61 |
+
def decode_base64_to_pil(encoding):
|
62 |
+
if encoding.startswith("data:image/"):
|
63 |
+
encoding = encoding.split(";")[1].split(",")[1]
|
64 |
+
return Image.open(io.BytesIO(base64.b64decode(encoding)))
|
65 |
+
|
66 |
+
|
67 |
+
def encode_pil_to_base64(image):
|
68 |
+
with io.BytesIO() as output_bytes:
|
69 |
+
|
70 |
+
# Copy any text-only metadata
|
71 |
+
use_metadata = False
|
72 |
+
metadata = PngImagePlugin.PngInfo()
|
73 |
+
for key, value in image.info.items():
|
74 |
+
if isinstance(key, str) and isinstance(value, str):
|
75 |
+
metadata.add_text(key, value)
|
76 |
+
use_metadata = True
|
77 |
+
|
78 |
+
image.save(
|
79 |
+
output_bytes, "PNG", pnginfo=(metadata if use_metadata else None)
|
80 |
+
)
|
81 |
+
bytes_data = output_bytes.getvalue()
|
82 |
+
return base64.b64encode(bytes_data)
|
83 |
+
|
84 |
+
|
85 |
+
def open_folder(f):
|
86 |
+
if not os.path.exists(f):
|
87 |
+
print(f'Folder "{f}" does not exist. After you create an image, the folder will be created.')
|
88 |
+
return
|
89 |
+
elif not os.path.isdir(f):
|
90 |
+
print(f"""
|
91 |
+
WARNING
|
92 |
+
An open_folder request was made with an argument that is not a folder.
|
93 |
+
This could be an error or a malicious attempt to run code on your computer.
|
94 |
+
Requested path was: {f}
|
95 |
+
""", file=sys.stderr)
|
96 |
+
return
|
97 |
+
|
98 |
+
if not shared.cmd_opts.hide_ui_dir_config:
|
99 |
+
path = os.path.normpath(f)
|
100 |
+
if platform.system() == "Windows":
|
101 |
+
os.startfile(path)
|
102 |
+
elif platform.system() == "Darwin":
|
103 |
+
sp.Popen(["open", path])
|
104 |
+
elif "microsoft-standard-WSL2" in platform.uname().release:
|
105 |
+
sp.Popen(["wsl-open", path])
|
106 |
+
else:
|
107 |
+
sp.Popen(["xdg-open", path])
|
108 |
+
|
109 |
+
|
110 |
+
def copy_metadata_to_all(module, model_path, copy_dir, same_session_only, missing_meta_only, cover_image):
|
111 |
+
"""
|
112 |
+
Given a model with metadata, copies that metadata to all models in copy_dir.
|
113 |
+
|
114 |
+
:str module: Module name ("LoRA")
|
115 |
+
:str model: Model key in lora_models ("MyModel(123456abcdef)")
|
116 |
+
:str copy_dir: Directory to copy to
|
117 |
+
:bool same_session_only: Only copy to modules with the same ss_session_id
|
118 |
+
:bool missing_meta_only: Only copy to modules that are missing user metadata
|
119 |
+
:Optional[Image] cover_image: Cover image to embed in the file as base64
|
120 |
+
:returns: gr.HTML.update()
|
121 |
+
"""
|
122 |
+
if model_path == "None":
|
123 |
+
return "No model selected."
|
124 |
+
|
125 |
+
if not os.path.isfile(model_path):
|
126 |
+
return f"Model path not found: {model_path}"
|
127 |
+
|
128 |
+
model_path = os.path.realpath(model_path)
|
129 |
+
|
130 |
+
if os.path.splitext(model_path)[1] != ".safetensors":
|
131 |
+
return "Model is not in .safetensors format."
|
132 |
+
|
133 |
+
if not os.path.isdir(copy_dir):
|
134 |
+
return "Please provide a directory containing models in .safetensors format."
|
135 |
+
|
136 |
+
print(f"[MetadataEditor] Copying metadata to models in {copy_dir}.")
|
137 |
+
metadata = model_util.read_model_metadata(model_path, module)
|
138 |
+
count = 0
|
139 |
+
for entry in os.scandir(copy_dir):
|
140 |
+
if entry.is_file():
|
141 |
+
path = os.path.realpath(os.path.join(copy_dir, entry.name))
|
142 |
+
if path != model_path and model_util.is_safetensors(path):
|
143 |
+
if same_session_only:
|
144 |
+
other_metadata = safetensors_hack.read_metadata(path)
|
145 |
+
if missing_meta_only and other_metadata.get("ssmd_display_name", "").strip():
|
146 |
+
print(f"[MetadataEditor] Skipping {path} as it already has metadata")
|
147 |
+
continue
|
148 |
+
|
149 |
+
session_id = metadata.get("ss_session_id", None)
|
150 |
+
other_session_id = other_metadata.get("ss_session_id", None)
|
151 |
+
if session_id is None or other_session_id is None or session_id != other_session_id:
|
152 |
+
continue
|
153 |
+
|
154 |
+
updates = {
|
155 |
+
"ssmd_cover_images": "[]",
|
156 |
+
"ssmd_display_name": "",
|
157 |
+
"ssmd_version": "",
|
158 |
+
"ssmd_keywords": "",
|
159 |
+
"ssmd_author": "",
|
160 |
+
"ssmd_source": "",
|
161 |
+
"ssmd_description": "",
|
162 |
+
"ssmd_rating": "0",
|
163 |
+
"ssmd_tags": "",
|
164 |
+
}
|
165 |
+
|
166 |
+
for k, v in metadata.items():
|
167 |
+
if k.startswith("ssmd_") and k != "ssmd_cover_images":
|
168 |
+
updates[k] = v
|
169 |
+
|
170 |
+
model_util.write_model_metadata(path, module, updates)
|
171 |
+
count += 1
|
172 |
+
|
173 |
+
print(f"[MetadataEditor] Updated {count} models in directory {copy_dir}.")
|
174 |
+
return f"Updated {count} models in directory {copy_dir}."
|
175 |
+
|
176 |
+
|
177 |
+
def load_cover_image(model_path, metadata):
|
178 |
+
"""
|
179 |
+
Loads a cover image either from embedded metadata or an image file with
|
180 |
+
.preview.png/.png format
|
181 |
+
"""
|
182 |
+
cover_images = json.loads(metadata.get("ssmd_cover_images", "[]"))
|
183 |
+
cover_image = None
|
184 |
+
if len(cover_images) > 0:
|
185 |
+
print("[MetadataEditor] Loading embedded cover image.")
|
186 |
+
cover_image = decode_base64_to_pil(cover_images[0])
|
187 |
+
else:
|
188 |
+
basename, ext = os.path.splitext(model_path)
|
189 |
+
|
190 |
+
preview_paths = [f"{basename}.preview.png", f"{basename}.png"]
|
191 |
+
|
192 |
+
for preview_path in preview_paths:
|
193 |
+
if os.path.isfile(preview_path):
|
194 |
+
print(f"[MetadataEditor] Loading webui preview image: {preview_path}")
|
195 |
+
cover_image = Image.open(preview_path)
|
196 |
+
|
197 |
+
return cover_image
|
198 |
+
|
199 |
+
|
200 |
+
# Dummy value since gr.Dataframe cannot handle an empty list
|
201 |
+
# https://github.com/gradio-app/gradio/issues/3182
|
202 |
+
unknown_folders = ["(Unknown)", 0, 0, 0]
|
203 |
+
|
204 |
+
|
205 |
+
def refresh_metadata(module, model_path):
|
206 |
+
"""
|
207 |
+
Reads metadata from the model on disk and updates all Gradio components
|
208 |
+
"""
|
209 |
+
if model_path == "None":
|
210 |
+
return {}, None, "", "", "", "", "", 0, "", "", "", "", "", {}, [unknown_folders]
|
211 |
+
|
212 |
+
if not os.path.isfile(model_path):
|
213 |
+
return {"info": f"Model path not found: {model_path}"}, None, "", "", "", "", "", 0, "", "", "", "", "", {}, [unknown_folders]
|
214 |
+
|
215 |
+
if os.path.splitext(model_path)[1] != ".safetensors":
|
216 |
+
return {"info": "Model is not in .safetensors format."}, None, "", "", "", "", "", 0, "", "", "", "", "", {}, [unknown_folders]
|
217 |
+
|
218 |
+
metadata = model_util.read_model_metadata(model_path, module)
|
219 |
+
|
220 |
+
if metadata is None:
|
221 |
+
training_params = {}
|
222 |
+
metadata = {}
|
223 |
+
else:
|
224 |
+
training_params = {k: v for k, v in metadata.items() if k.startswith("ss_")}
|
225 |
+
|
226 |
+
cover_image = load_cover_image(model_path, metadata)
|
227 |
+
|
228 |
+
display_name = metadata.get("ssmd_display_name", "")
|
229 |
+
author = metadata.get("ssmd_author", "")
|
230 |
+
#version = metadata.get("ssmd_version", "")
|
231 |
+
source = metadata.get("ssmd_source", "")
|
232 |
+
keywords = metadata.get("ssmd_keywords", "")
|
233 |
+
description = metadata.get("ssmd_description", "")
|
234 |
+
rating = int(metadata.get("ssmd_rating", "0"))
|
235 |
+
tags = metadata.get("ssmd_tags", "")
|
236 |
+
model_hash = metadata.get("sshs_model_hash", model_util.cache("hashes").get(model_path, {}).get("model", ""))
|
237 |
+
legacy_hash = metadata.get("sshs_legacy_hash", model_util.cache("hashes").get(model_path, {}).get("legacy", ""))
|
238 |
+
|
239 |
+
top_tags = {}
|
240 |
+
if "ss_tag_frequency" in training_params:
|
241 |
+
tag_frequency = json.loads(training_params.pop("ss_tag_frequency"))
|
242 |
+
count_max = 0
|
243 |
+
for dir, frequencies in tag_frequency.items():
|
244 |
+
for tag, count in frequencies.items():
|
245 |
+
tag = tag.strip()
|
246 |
+
existing = top_tags.get(tag, 0)
|
247 |
+
top_tags[tag] = count + existing
|
248 |
+
if len(top_tags) > 0:
|
249 |
+
top_tags = dict(sorted(top_tags.items(), key=lambda x: x[1], reverse=True))
|
250 |
+
|
251 |
+
count_max = max(top_tags.values())
|
252 |
+
top_tags = {k: float(v / count_max) for k, v in top_tags.items()}
|
253 |
+
|
254 |
+
dataset_folders = []
|
255 |
+
if "ss_dataset_dirs" in training_params:
|
256 |
+
dataset_dirs = json.loads(training_params.pop("ss_dataset_dirs"))
|
257 |
+
for dir, counts in dataset_dirs.items():
|
258 |
+
img_count = int(counts["img_count"])
|
259 |
+
n_repeats = int(counts["n_repeats"])
|
260 |
+
dataset_folders.append([dir, img_count, n_repeats, img_count * n_repeats])
|
261 |
+
if dataset_folders:
|
262 |
+
dataset_folders.append(["(Total)", sum(r[1] for r in dataset_folders), sum(r[2] for r in dataset_folders), sum(r[3] for r in dataset_folders)])
|
263 |
+
else:
|
264 |
+
dataset_folders.append(unknown_folders)
|
265 |
+
|
266 |
+
return training_params, cover_image, display_name, author, source, keywords, description, rating, tags, model_hash, legacy_hash, model_path, os.path.dirname(model_path), top_tags, dataset_folders
|
267 |
+
|
268 |
+
|
269 |
+
def save_metadata(module, model_path, cover_image, display_name, author, source, keywords, description, rating, tags):
|
270 |
+
"""
|
271 |
+
Writes metadata from the Gradio components to the model file
|
272 |
+
"""
|
273 |
+
if model_path == "None":
|
274 |
+
return "No model selected.", "", ""
|
275 |
+
|
276 |
+
if not os.path.isfile(model_path):
|
277 |
+
return f"file not found: {model_path}", "", ""
|
278 |
+
|
279 |
+
if os.path.splitext(model_path)[1] != ".safetensors":
|
280 |
+
return "Model is not in .safetensors format", "", ""
|
281 |
+
|
282 |
+
metadata = safetensors_hack.read_metadata(model_path)
|
283 |
+
model_hash = safetensors_hack.hash_file(model_path)
|
284 |
+
legacy_hash = model_util.get_legacy_hash(metadata, model_path)
|
285 |
+
|
286 |
+
# TODO: Support multiple images
|
287 |
+
# Blocked on gradio not having a gallery upload option
|
288 |
+
# https://github.com/gradio-app/gradio/issues/1379
|
289 |
+
cover_images = []
|
290 |
+
if cover_image is not None:
|
291 |
+
cover_images.append(encode_pil_to_base64(cover_image).decode("ascii"))
|
292 |
+
|
293 |
+
# NOTE: User-specified metadata should NOT be prefixed with "ss_". This is
|
294 |
+
# to maintain backwards compatibility with the old hashing method. "ss_"
|
295 |
+
# should be used for training parameters that will never be manually
|
296 |
+
# updated on the model.
|
297 |
+
updates = {
|
298 |
+
"ssmd_cover_images": json.dumps(cover_images),
|
299 |
+
"ssmd_display_name": display_name,
|
300 |
+
"ssmd_author": author,
|
301 |
+
# "ssmd_version": version,
|
302 |
+
"ssmd_source": source,
|
303 |
+
"ssmd_keywords": keywords,
|
304 |
+
"ssmd_description": description,
|
305 |
+
"ssmd_rating": rating,
|
306 |
+
"ssmd_tags": tags,
|
307 |
+
"sshs_model_hash": model_hash,
|
308 |
+
"sshs_legacy_hash": legacy_hash
|
309 |
+
}
|
310 |
+
|
311 |
+
model_util.write_model_metadata(model_path, module, updates)
|
312 |
+
if cover_image is None:
|
313 |
+
delete_webui_model_preview_image(model_path)
|
314 |
+
else:
|
315 |
+
write_webui_model_preview_image(model_path, cover_image)
|
316 |
+
|
317 |
+
model_name = os.path.basename(model_path)
|
318 |
+
return f"Model saved: {model_name}", model_hash, legacy_hash
|
319 |
+
|
320 |
+
|
321 |
+
model_name_filter = ""
|
322 |
+
|
323 |
+
|
324 |
+
def get_filtered_model_paths(s):
|
325 |
+
if not s:
|
326 |
+
return ["None"] + list(model_util.lora_models.values())
|
327 |
+
|
328 |
+
return ["None"] + [v for v in model_util.lora_models.values() if v and s in v.lower()]
|
329 |
+
|
330 |
+
|
331 |
+
def get_filtered_model_paths_global():
|
332 |
+
global model_name_filter
|
333 |
+
return get_filtered_model_paths(model_name_filter)
|
334 |
+
|
335 |
+
|
336 |
+
def setup_ui(addnet_paste_params):
|
337 |
+
"""
|
338 |
+
:dict addnet_paste_params: Dictionary of txt2img/img2img controls for each model weight slider,
|
339 |
+
for sending module and model to them from the metadata editor
|
340 |
+
"""
|
341 |
+
can_edit = False
|
342 |
+
|
343 |
+
with gr.Row().style(equal_height=False):
|
344 |
+
|
345 |
+
# Lefthand column
|
346 |
+
with gr.Column(variant='panel'):
|
347 |
+
|
348 |
+
# Module and model selector
|
349 |
+
with gr.Row():
|
350 |
+
model_filter = gr.Textbox("", label="Model path filter", placeholder="Filter models by path name")
|
351 |
+
def update_model_filter(s):
|
352 |
+
global model_name_filter
|
353 |
+
model_name_filter = s.strip().lower()
|
354 |
+
model_filter.change(update_model_filter, inputs=[model_filter], outputs=[])
|
355 |
+
with gr.Row():
|
356 |
+
module = gr.Dropdown(["LoRA"], label="Network module", value="LoRA", interactive=True, elem_id="additional_networks_metadata_editor_module")
|
357 |
+
model = gr.Dropdown(get_filtered_model_paths_global(), label="Model", value="None", interactive=True,
|
358 |
+
elem_id="additional_networks_metadata_editor_model")
|
359 |
+
modules.ui.create_refresh_button(model, model_util.update_models, lambda: {"choices": get_filtered_model_paths_global()}, "refresh_lora_models")
|
360 |
+
|
361 |
+
def submit_model_filter(s):
|
362 |
+
global model_name_filter
|
363 |
+
model_name_filter = s
|
364 |
+
paths = get_filtered_model_paths(s)
|
365 |
+
return gr.Dropdown.update(choices=paths, value="None")
|
366 |
+
model_filter.submit(submit_model_filter, inputs=[model_filter], outputs=[model])
|
367 |
+
|
368 |
+
# Model hashes and path
|
369 |
+
with gr.Row():
|
370 |
+
model_hash = gr.Textbox("", label="Model hash", interactive=False)
|
371 |
+
legacy_hash = gr.Textbox("", label="Legacy hash", interactive=False)
|
372 |
+
with gr.Row():
|
373 |
+
model_path = gr.Textbox("", label="Model path", interactive=False)
|
374 |
+
open_folder_button = ToolButton(value=folder_symbol, elem_id="hidden_element" if shared.cmd_opts.hide_ui_dir_config else "open_folder_metadata_editor")
|
375 |
+
|
376 |
+
# Send to txt2img/img2img buttons
|
377 |
+
for tabname in ["txt2img", "img2img"]:
|
378 |
+
with gr.Row():
|
379 |
+
with gr.Box():
|
380 |
+
with gr.Row():
|
381 |
+
gr.HTML(f"Send to {tabname}:")
|
382 |
+
for i in range(MAX_MODEL_COUNT):
|
383 |
+
send_to_button = ToolButton(value=keycap_symbols[i], elem_id=f"additional_networks_send_to_{tabname}_{i}")
|
384 |
+
send_to_button.click(fn=lambda modu, mod: (modu, model_util.find_closest_lora_model_name(mod) or "None"), inputs=[module, model], outputs=[addnet_paste_params[tabname][i]["module"], addnet_paste_params[tabname][i]["model"]])
|
385 |
+
send_to_button.click(fn=None,_js=f"addnet_switch_to_{tabname}", inputs=None, outputs=None)
|
386 |
+
|
387 |
+
# "Copy metadata to other models" panel
|
388 |
+
with gr.Row():
|
389 |
+
with gr.Column():
|
390 |
+
gr.HTML(value="Copy metadata to other models in directory")
|
391 |
+
copy_metadata_dir = gr.Textbox("", label="Containing directory", placeholder="All models in this directory will receive the selected model's metadata")
|
392 |
+
with gr.Row():
|
393 |
+
copy_same_session = gr.Checkbox(True, label="Only copy to models with same session ID")
|
394 |
+
copy_no_metadata = gr.Checkbox(True, label="Only copy to models with no metadata")
|
395 |
+
copy_metadata_button = gr.Button("Copy Metadata", variant="primary")
|
396 |
+
|
397 |
+
# Center column, metadata viewer/editor
|
398 |
+
with gr.Column():
|
399 |
+
with gr.Row():
|
400 |
+
display_name = gr.Textbox(value="", label="Name", placeholder="Display name for this model", interactive=can_edit)
|
401 |
+
author = gr.Textbox(value="", label="Author", placeholder="Author of this model", interactive=can_edit)
|
402 |
+
with gr.Row():
|
403 |
+
keywords = gr.Textbox(value="", label="Keywords", placeholder="Activation keywords, comma-separated", interactive=can_edit)
|
404 |
+
with gr.Row():
|
405 |
+
description = gr.Textbox(value="", label="Description", placeholder="Model description/readme/notes/instructions", lines=15, interactive=can_edit)
|
406 |
+
with gr.Row():
|
407 |
+
source = gr.Textbox(value="", label="Source", placeholder="Source URL where this model could be found", interactive=can_edit)
|
408 |
+
with gr.Row():
|
409 |
+
rating = gr.Slider(minimum=0, maximum=10, step=1, label="Rating", value=0, interactive=can_edit)
|
410 |
+
tags = gr.Textbox(value="", label="Tags", placeholder="Comma-separated list of tags (\"artist, style, character, 2d, 3d...\")", lines=2, interactive=can_edit)
|
411 |
+
with gr.Row():
|
412 |
+
editing_enabled = gr.Checkbox(label="Editing Enabled", value=can_edit)
|
413 |
+
with gr.Row():
|
414 |
+
save_metadata_button = gr.Button("Save Metadata", variant="primary", interactive=can_edit)
|
415 |
+
with gr.Row():
|
416 |
+
save_output = gr.HTML("")
|
417 |
+
|
418 |
+
# Righthand column, cover image and training parameters view
|
419 |
+
with gr.Column():
|
420 |
+
|
421 |
+
# Cover image
|
422 |
+
with gr.Row():
|
423 |
+
cover_image = gr.Image(label="Cover image", elem_id="additional_networks_cover_image", source="upload", interactive=can_edit, type="pil", image_mode="RGBA").style(height=480)
|
424 |
+
|
425 |
+
# Image parameters
|
426 |
+
with gr.Accordion("Image Parameters", open=False):
|
427 |
+
with gr.Row():
|
428 |
+
info2 = gr.HTML()
|
429 |
+
with gr.Row():
|
430 |
+
try:
|
431 |
+
send_to_buttons = parameters_copypaste.create_buttons(["txt2img", "img2img", "inpaint", "extras"])
|
432 |
+
except:
|
433 |
+
pass
|
434 |
+
|
435 |
+
# Training info, below cover image
|
436 |
+
with gr.Accordion("Training info", open=False):
|
437 |
+
|
438 |
+
# Top tags used
|
439 |
+
with gr.Row():
|
440 |
+
max_top_tags = int(shared.opts.data.get("additional_networks_max_top_tags", 20))
|
441 |
+
most_frequent_tags = gr.Label(value={}, label="Most frequent tags in captions", num_top_classes=max_top_tags)
|
442 |
+
|
443 |
+
# Dataset folders
|
444 |
+
with gr.Row():
|
445 |
+
max_dataset_folders = int(shared.opts.data.get("additional_networks_max_dataset_folders", 20))
|
446 |
+
dataset_folders = gr.Dataframe(
|
447 |
+
headers=["Name", "Image Count", "Repeats", "Total Images"],
|
448 |
+
datatype=["str", "number", "number", "number"],
|
449 |
+
label="Dataset folder structure",
|
450 |
+
max_rows=max_dataset_folders,
|
451 |
+
col_count=(4, "fixed"))
|
452 |
+
|
453 |
+
# Training Parameters
|
454 |
+
with gr.Row():
|
455 |
+
metadata_view = gr.JSON(value={}, label="Training parameters")
|
456 |
+
|
457 |
+
# Hidden/internal
|
458 |
+
with gr.Row(visible=False):
|
459 |
+
info1 = gr.HTML()
|
460 |
+
img_file_info = gr.Textbox(label="Generate Info", interactive=False, lines=6)
|
461 |
+
|
462 |
+
open_folder_button.click(fn=lambda p: open_folder(os.path.dirname(p)), inputs=[model_path], outputs=[])
|
463 |
+
copy_metadata_button.click(fn=copy_metadata_to_all, inputs=[module, model, copy_metadata_dir, copy_same_session, copy_no_metadata, cover_image], outputs=[save_output])
|
464 |
+
|
465 |
+
def update_editing(enabled):
|
466 |
+
"""
|
467 |
+
Enable/disable components based on "Editing Enabled" status
|
468 |
+
"""
|
469 |
+
updates = [gr.Textbox.update(interactive=enabled)] * 6
|
470 |
+
updates.append(gr.Image.update(interactive=enabled))
|
471 |
+
updates.append(gr.Slider.update(interactive=enabled))
|
472 |
+
updates.append(gr.Button.update(interactive=enabled))
|
473 |
+
return updates
|
474 |
+
editing_enabled.change(fn=update_editing, inputs=[editing_enabled], outputs=[display_name, author, source, keywords, description, tags, cover_image, rating, save_metadata_button])
|
475 |
+
|
476 |
+
cover_image.change(fn=modules.extras.run_pnginfo, inputs=[cover_image], outputs=[info1, img_file_info, info2])
|
477 |
+
|
478 |
+
try:
|
479 |
+
parameters_copypaste.bind_buttons(send_to_buttons, cover_image, img_file_info)
|
480 |
+
except:
|
481 |
+
pass
|
482 |
+
|
483 |
+
model.change(refresh_metadata, inputs=[module, model], outputs=[metadata_view, cover_image, display_name, author, source, keywords, description, rating, tags, model_hash, legacy_hash, model_path, copy_metadata_dir, most_frequent_tags, dataset_folders])
|
484 |
+
save_metadata_button.click(save_metadata, inputs=[module, model, cover_image, display_name, author, source, keywords, description, rating, tags], outputs=[save_output, model_hash, legacy_hash])
|
ex/additional-networks/scripts/model_util.py
ADDED
@@ -0,0 +1,334 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import os.path
|
3 |
+
import re
|
4 |
+
import shutil
|
5 |
+
import json
|
6 |
+
import stat
|
7 |
+
import tqdm
|
8 |
+
from collections import OrderedDict
|
9 |
+
from multiprocessing.pool import ThreadPool as Pool
|
10 |
+
|
11 |
+
from modules import shared, sd_models, hashes
|
12 |
+
from scripts import safetensors_hack, model_util, util
|
13 |
+
import modules.scripts as scripts
|
14 |
+
|
15 |
+
|
16 |
+
# MAX_MODEL_COUNT = shared.cmd_opts.addnet_max_model_count or 5
|
17 |
+
MAX_MODEL_COUNT = shared.cmd_opts.addnet_max_model_count if hasattr(shared.cmd_opts, "addnet_max_model_count") else 5
|
18 |
+
LORA_MODEL_EXTS = [".pt", ".ckpt", ".safetensors"]
|
19 |
+
re_legacy_hash = re.compile("\(([0-9a-f]{8})\)$") # matches 8-character hashes, new hash has 12 characters
|
20 |
+
lora_models = {} # "My_Lora(abcdef123456)" -> "C:/path/to/model.safetensors"
|
21 |
+
lora_model_names = {} # "my_lora" -> "My_Lora(My_Lora(abcdef123456)"
|
22 |
+
legacy_model_names = {}
|
23 |
+
lora_models_dir = os.path.join(scripts.basedir(), "models/lora")
|
24 |
+
os.makedirs(lora_models_dir, exist_ok=True)
|
25 |
+
|
26 |
+
|
27 |
+
def is_safetensors(filename):
|
28 |
+
return os.path.splitext(filename)[1] == ".safetensors"
|
29 |
+
|
30 |
+
|
31 |
+
def read_model_metadata(model_path, module):
|
32 |
+
if model_path.startswith("\"") and model_path.endswith("\""): # trim '"' at start/end
|
33 |
+
model_path = model_path[1:-1]
|
34 |
+
if not os.path.exists(model_path):
|
35 |
+
return None
|
36 |
+
|
37 |
+
metadata = None
|
38 |
+
if module == "LoRA":
|
39 |
+
if os.path.splitext(model_path)[1] == '.safetensors':
|
40 |
+
metadata = safetensors_hack.read_metadata(model_path)
|
41 |
+
|
42 |
+
return metadata
|
43 |
+
|
44 |
+
|
45 |
+
def write_model_metadata(model_path, module, updates):
|
46 |
+
if model_path.startswith("\"") and model_path.endswith("\""): # trim '"' at start/end
|
47 |
+
model_path = model_path[1:-1]
|
48 |
+
if not os.path.exists(model_path):
|
49 |
+
return None
|
50 |
+
|
51 |
+
from safetensors.torch import save_file
|
52 |
+
|
53 |
+
back_up = shared.opts.data.get("additional_networks_back_up_model_when_saving", True)
|
54 |
+
if back_up:
|
55 |
+
backup_path = model_path + ".backup"
|
56 |
+
if not os.path.exists(backup_path):
|
57 |
+
print(f"[MetadataEditor] Backing up current model to {backup_path}")
|
58 |
+
shutil.copyfile(model_path, backup_path)
|
59 |
+
|
60 |
+
metadata = None
|
61 |
+
tensors = {}
|
62 |
+
if module == "LoRA":
|
63 |
+
if os.path.splitext(model_path)[1] == '.safetensors':
|
64 |
+
tensors, metadata = safetensors_hack.load_file(model_path, "cpu")
|
65 |
+
|
66 |
+
for k, v in updates.items():
|
67 |
+
metadata[k] = str(v)
|
68 |
+
|
69 |
+
save_file(tensors, model_path, metadata)
|
70 |
+
print(f"[MetadataEditor] Model saved: {model_path}")
|
71 |
+
|
72 |
+
|
73 |
+
def get_model_list(module, model, model_dir, sort_by):
|
74 |
+
if model_dir == "":
|
75 |
+
# Get list of models with same folder as this one
|
76 |
+
model_path = lora_models.get(model, None)
|
77 |
+
if model_path is None:
|
78 |
+
return []
|
79 |
+
model_dir = os.path.dirname(model_path)
|
80 |
+
|
81 |
+
if not os.path.isdir(model_dir):
|
82 |
+
return []
|
83 |
+
|
84 |
+
found, _ = get_all_models([model_dir], sort_by, "")
|
85 |
+
return found.keys()
|
86 |
+
|
87 |
+
|
88 |
+
def traverse_all_files(curr_path, model_list):
|
89 |
+
f_list = [(os.path.join(curr_path, entry.name), entry.stat()) for entry in os.scandir(curr_path)]
|
90 |
+
for f_info in f_list:
|
91 |
+
fname, fstat = f_info
|
92 |
+
if os.path.splitext(fname)[1] in LORA_MODEL_EXTS:
|
93 |
+
model_list.append(f_info)
|
94 |
+
elif stat.S_ISDIR(fstat.st_mode):
|
95 |
+
model_list = traverse_all_files(fname, model_list)
|
96 |
+
return model_list
|
97 |
+
|
98 |
+
|
99 |
+
def get_model_hash(metadata, filename):
|
100 |
+
if metadata is None:
|
101 |
+
return hashes.calculate_sha256(filename)
|
102 |
+
|
103 |
+
if "sshs_model_hash" in metadata:
|
104 |
+
return metadata["sshs_model_hash"]
|
105 |
+
|
106 |
+
return safetensors_hack.hash_file(filename)
|
107 |
+
|
108 |
+
|
109 |
+
def get_legacy_hash(metadata, filename):
|
110 |
+
if metadata is None:
|
111 |
+
return sd_models.model_hash(filename)
|
112 |
+
|
113 |
+
if "sshs_legacy_hash" in metadata:
|
114 |
+
return metadata["sshs_legacy_hash"]
|
115 |
+
|
116 |
+
return safetensors_hack.legacy_hash_file(filename)
|
117 |
+
|
118 |
+
|
119 |
+
import filelock
|
120 |
+
cache_filename = os.path.join(scripts.basedir(), "hashes.json")
|
121 |
+
cache_data = None
|
122 |
+
|
123 |
+
|
124 |
+
def cache(subsection):
|
125 |
+
global cache_data
|
126 |
+
|
127 |
+
if cache_data is None:
|
128 |
+
with filelock.FileLock(cache_filename+".lock"):
|
129 |
+
if not os.path.isfile(cache_filename):
|
130 |
+
cache_data = {}
|
131 |
+
else:
|
132 |
+
with open(cache_filename, "r", encoding="utf8") as file:
|
133 |
+
cache_data = json.load(file)
|
134 |
+
|
135 |
+
s = cache_data.get(subsection, {})
|
136 |
+
cache_data[subsection] = s
|
137 |
+
|
138 |
+
return s
|
139 |
+
|
140 |
+
|
141 |
+
def dump_cache():
|
142 |
+
with filelock.FileLock(cache_filename+".lock"):
|
143 |
+
with open(cache_filename, "w", encoding="utf8") as file:
|
144 |
+
json.dump(cache_data, file, indent=4)
|
145 |
+
|
146 |
+
|
147 |
+
def get_model_rating(filename):
|
148 |
+
if not model_util.is_safetensors(filename):
|
149 |
+
return 0
|
150 |
+
|
151 |
+
metadata = safetensors_hack.read_metadata(filename)
|
152 |
+
return int(metadata.get("ssmd_rating", "0"))
|
153 |
+
|
154 |
+
|
155 |
+
def has_user_metadata(filename):
|
156 |
+
if not model_util.is_safetensors(filename):
|
157 |
+
return False
|
158 |
+
|
159 |
+
metadata = safetensors_hack.read_metadata(filename)
|
160 |
+
return any(k.startswith("ssmd_") for k in metadata.keys())
|
161 |
+
|
162 |
+
|
163 |
+
def hash_model_file(finfo):
|
164 |
+
filename = finfo[0]
|
165 |
+
stat = finfo[1]
|
166 |
+
name = os.path.splitext(os.path.basename(filename))[0]
|
167 |
+
|
168 |
+
# Prevent a hypothetical "None.pt" from being listed.
|
169 |
+
if name != "None":
|
170 |
+
metadata = None
|
171 |
+
|
172 |
+
cached = cache("hashes").get(filename, None)
|
173 |
+
if cached is None or stat.st_mtime != cached["mtime"]:
|
174 |
+
if metadata is None and model_util.is_safetensors(filename):
|
175 |
+
try:
|
176 |
+
metadata = safetensors_hack.read_metadata(filename)
|
177 |
+
except Exception as ex:
|
178 |
+
return {"error": ex, "filename": filename}
|
179 |
+
model_hash = get_model_hash(metadata, filename)
|
180 |
+
legacy_hash = get_legacy_hash(metadata, filename)
|
181 |
+
else:
|
182 |
+
model_hash = cached["model"]
|
183 |
+
legacy_hash = cached["legacy"]
|
184 |
+
|
185 |
+
return {"model": model_hash, "legacy": legacy_hash, "fileinfo": finfo}
|
186 |
+
|
187 |
+
|
188 |
+
def get_all_models(paths, sort_by, filter_by):
|
189 |
+
fileinfos = []
|
190 |
+
for path in paths:
|
191 |
+
if os.path.isdir(path):
|
192 |
+
fileinfos += traverse_all_files(path, [])
|
193 |
+
|
194 |
+
show_only_safetensors = shared.opts.data.get("additional_networks_show_only_safetensors", False)
|
195 |
+
show_only_missing_meta = shared.opts.data.get("additional_networks_show_only_models_with_metadata", "disabled")
|
196 |
+
|
197 |
+
if show_only_safetensors:
|
198 |
+
fileinfos = [x for x in fileinfos if is_safetensors(x[0])]
|
199 |
+
|
200 |
+
if show_only_missing_meta == "has metadata":
|
201 |
+
fileinfos = [x for x in fileinfos if has_user_metadata(x[0])]
|
202 |
+
elif show_only_missing_meta == "missing metadata":
|
203 |
+
fileinfos = [x for x in fileinfos if not has_user_metadata(x[0])]
|
204 |
+
|
205 |
+
print("[AddNet] Updating model hashes...")
|
206 |
+
data = []
|
207 |
+
thread_count = max(1, int(shared.opts.data.get("additional_networks_hash_thread_count", 1)))
|
208 |
+
p = Pool(processes=thread_count)
|
209 |
+
with tqdm.tqdm(total=len(fileinfos)) as pbar:
|
210 |
+
for res in p.imap_unordered(hash_model_file, fileinfos):
|
211 |
+
pbar.update()
|
212 |
+
if "error" in res:
|
213 |
+
print(f"Failed to read model file {res['filename']}: {res['error']}")
|
214 |
+
else:
|
215 |
+
data.append(res)
|
216 |
+
p.close()
|
217 |
+
|
218 |
+
cache_hashes = cache("hashes")
|
219 |
+
|
220 |
+
res = OrderedDict()
|
221 |
+
res_legacy = OrderedDict()
|
222 |
+
filter_by = filter_by.strip(" ")
|
223 |
+
if len(filter_by) != 0:
|
224 |
+
data = [x for x in data if filter_by.lower() in os.path.basename(x["fileinfo"][0]).lower()]
|
225 |
+
if sort_by == "name":
|
226 |
+
data = sorted(data, key=lambda x: os.path.basename(x["fileinfo"][0]))
|
227 |
+
elif sort_by == "date":
|
228 |
+
data = sorted(data, key=lambda x: -x["fileinfo"][1].st_mtime)
|
229 |
+
elif sort_by == "path name":
|
230 |
+
data = sorted(data, key=lambda x: x["fileinfo"][0])
|
231 |
+
elif sort_by == "rating":
|
232 |
+
data = sorted(data, key=lambda x: get_model_rating(x["fileinfo"][0]), reverse=True)
|
233 |
+
elif sort_by == "has user metadata":
|
234 |
+
data = sorted(data, key=lambda x: os.path.basename(x["fileinfo"][0]) if has_user_metadata(x["fileinfo"][0]) else "", reverse=True)
|
235 |
+
|
236 |
+
reverse = shared.opts.data.get("additional_networks_reverse_sort_order", False)
|
237 |
+
if reverse:
|
238 |
+
data = reversed(data)
|
239 |
+
|
240 |
+
for result in data:
|
241 |
+
finfo = result["fileinfo"]
|
242 |
+
filename = finfo[0]
|
243 |
+
stat = finfo[1]
|
244 |
+
model_hash = result["model"]
|
245 |
+
legacy_hash = result["legacy"]
|
246 |
+
|
247 |
+
name = os.path.splitext(os.path.basename(filename))[0]
|
248 |
+
|
249 |
+
# Commas in the model name will mess up infotext restoration since the
|
250 |
+
# infotext is delimited by commas
|
251 |
+
name = name.replace(",", "_")
|
252 |
+
|
253 |
+
# Prevent a hypothetical "None.pt" from being listed.
|
254 |
+
if name != "None":
|
255 |
+
full_name = name + f"({model_hash[0:12]})"
|
256 |
+
res[full_name] = filename
|
257 |
+
res_legacy[legacy_hash] = full_name
|
258 |
+
cache_hashes[filename] = {"model": model_hash, "legacy": legacy_hash, "mtime": stat.st_mtime}
|
259 |
+
|
260 |
+
return res, res_legacy
|
261 |
+
|
262 |
+
|
263 |
+
def find_closest_lora_model_name(search: str):
|
264 |
+
if not search or search == "None":
|
265 |
+
return None
|
266 |
+
|
267 |
+
# Match name and hash, case-sensitive
|
268 |
+
# "MyModel-epoch00002(abcdef123456)"
|
269 |
+
if search in lora_models:
|
270 |
+
return search
|
271 |
+
|
272 |
+
# Match model path, case-sensitive (from metadata editor)
|
273 |
+
# "C:/path/to/mymodel-epoch00002.safetensors"
|
274 |
+
if os.path.isfile(search):
|
275 |
+
import json
|
276 |
+
find = os.path.normpath(search)
|
277 |
+
value = next((k for k in lora_models.keys() if lora_models[k] == find), None)
|
278 |
+
if value:
|
279 |
+
return value
|
280 |
+
|
281 |
+
search = search.lower()
|
282 |
+
|
283 |
+
# Match full name, case-insensitive
|
284 |
+
# "mymodel-epoch00002"
|
285 |
+
if search in lora_model_names:
|
286 |
+
return lora_model_names.get(search)
|
287 |
+
|
288 |
+
# Match legacy hash (8 characters)
|
289 |
+
# "MyModel(abcd1234)"
|
290 |
+
result = re_legacy_hash.search(search)
|
291 |
+
if result is not None:
|
292 |
+
model_hash = result.group(1)
|
293 |
+
if model_hash in legacy_model_names:
|
294 |
+
new_model_name = legacy_model_names[model_hash]
|
295 |
+
return new_model_name
|
296 |
+
|
297 |
+
# Use any model with the search term as the prefix, case-insensitive, sorted
|
298 |
+
# by name length
|
299 |
+
# "mymodel"
|
300 |
+
applicable = [name for name in lora_model_names.keys() if search in name.lower()]
|
301 |
+
if not applicable:
|
302 |
+
return None
|
303 |
+
applicable = sorted(applicable, key=lambda name: len(name))
|
304 |
+
return lora_model_names[applicable[0]]
|
305 |
+
|
306 |
+
|
307 |
+
def update_models():
|
308 |
+
global lora_models, lora_model_names, legacy_model_names
|
309 |
+
paths = [lora_models_dir]
|
310 |
+
extra_lora_paths = util.split_path_list(shared.opts.data.get("additional_networks_extra_lora_path", ""))
|
311 |
+
for path in extra_lora_paths:
|
312 |
+
path = path.lstrip()
|
313 |
+
if os.path.isdir(path):
|
314 |
+
paths.append(path)
|
315 |
+
|
316 |
+
sort_by = shared.opts.data.get("additional_networks_sort_models_by", "name")
|
317 |
+
filter_by = shared.opts.data.get("additional_networks_model_name_filter", "")
|
318 |
+
res, res_legacy = get_all_models(paths, sort_by, filter_by)
|
319 |
+
|
320 |
+
lora_models.clear()
|
321 |
+
lora_models["None"] = None
|
322 |
+
lora_models.update(res)
|
323 |
+
|
324 |
+
for name_and_hash, filename in lora_models.items():
|
325 |
+
if filename == None:
|
326 |
+
continue
|
327 |
+
name = os.path.splitext(os.path.basename(filename))[0].lower()
|
328 |
+
lora_model_names[name] = name_and_hash
|
329 |
+
|
330 |
+
legacy_model_names = res_legacy
|
331 |
+
dump_cache()
|
332 |
+
|
333 |
+
|
334 |
+
update_models()
|
ex/additional-networks/scripts/safetensors_hack.py
ADDED
@@ -0,0 +1,116 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import io
|
2 |
+
import os
|
3 |
+
import mmap
|
4 |
+
import torch
|
5 |
+
import json
|
6 |
+
import hashlib
|
7 |
+
import safetensors
|
8 |
+
import safetensors.torch
|
9 |
+
|
10 |
+
from modules import sd_models
|
11 |
+
|
12 |
+
# PyTorch 1.13 and later have _UntypedStorage renamed to UntypedStorage
|
13 |
+
UntypedStorage = torch.storage.UntypedStorage if hasattr(torch.storage, 'UntypedStorage') else torch.storage._UntypedStorage
|
14 |
+
|
15 |
+
def read_metadata(filename):
|
16 |
+
"""Reads the JSON metadata from a .safetensors file"""
|
17 |
+
with open(filename, mode="r", encoding="utf8") as file_obj:
|
18 |
+
with mmap.mmap(file_obj.fileno(), length=0, access=mmap.ACCESS_READ) as m:
|
19 |
+
header = m.read(8)
|
20 |
+
n = int.from_bytes(header, "little")
|
21 |
+
metadata_bytes = m.read(n)
|
22 |
+
metadata = json.loads(metadata_bytes)
|
23 |
+
|
24 |
+
return metadata.get("__metadata__", {})
|
25 |
+
|
26 |
+
|
27 |
+
def load_file(filename, device):
|
28 |
+
""""Loads a .safetensors file without memory mapping that locks the model file.
|
29 |
+
Works around safetensors issue: https://github.com/huggingface/safetensors/issues/164"""
|
30 |
+
with open(filename, mode="r", encoding="utf8") as file_obj:
|
31 |
+
with mmap.mmap(file_obj.fileno(), length=0, access=mmap.ACCESS_READ) as m:
|
32 |
+
header = m.read(8)
|
33 |
+
n = int.from_bytes(header, "little")
|
34 |
+
metadata_bytes = m.read(n)
|
35 |
+
metadata = json.loads(metadata_bytes)
|
36 |
+
|
37 |
+
size = os.stat(filename).st_size
|
38 |
+
storage = UntypedStorage.from_file(filename, False, size)
|
39 |
+
offset = n + 8
|
40 |
+
md = metadata.get("__metadata__", {})
|
41 |
+
return {name: create_tensor(storage, info, offset) for name, info in metadata.items() if name != "__metadata__"}, md
|
42 |
+
|
43 |
+
|
44 |
+
def hash_file(filename):
|
45 |
+
"""Hashes a .safetensors file using the new hashing method.
|
46 |
+
Only hashes the weights of the model."""
|
47 |
+
hash_sha256 = hashlib.sha256()
|
48 |
+
blksize = 1024 * 1024
|
49 |
+
|
50 |
+
with open(filename, mode="r", encoding="utf8") as file_obj:
|
51 |
+
with mmap.mmap(file_obj.fileno(), length=0, access=mmap.ACCESS_READ) as m:
|
52 |
+
header = m.read(8)
|
53 |
+
n = int.from_bytes(header, "little")
|
54 |
+
|
55 |
+
with open(filename, mode="rb") as file_obj:
|
56 |
+
offset = n + 8
|
57 |
+
file_obj.seek(offset)
|
58 |
+
for chunk in iter(lambda: file_obj.read(blksize), b""):
|
59 |
+
hash_sha256.update(chunk)
|
60 |
+
|
61 |
+
return hash_sha256.hexdigest()
|
62 |
+
|
63 |
+
|
64 |
+
def legacy_hash_file(filename):
|
65 |
+
"""Hashes a model file using the legacy `sd_models.model_hash()` method."""
|
66 |
+
hash_sha256 = hashlib.sha256()
|
67 |
+
|
68 |
+
metadata = read_metadata(filename)
|
69 |
+
|
70 |
+
# For compatibility with legacy models: This replicates the behavior of
|
71 |
+
# sd_models.model_hash as if there were no user-specified metadata in the
|
72 |
+
# .safetensors file. That leaves the training parameters, which are
|
73 |
+
# immutable. It is important the hash does not include the embedded user
|
74 |
+
# metadata as that would mean the hash could change every time the user
|
75 |
+
# updates the name/description/etc. The new hashing method fixes this
|
76 |
+
# problem by only hashing the region of the file containing the tensors.
|
77 |
+
if any(not k.startswith("ss_") for k in metadata):
|
78 |
+
# Strip the user metadata, re-serialize the file as if it were freshly
|
79 |
+
# created from sd-scripts, and hash that with model_hash's behavior.
|
80 |
+
tensors, metadata = load_file(filename, "cpu")
|
81 |
+
metadata = {k: v for k, v in metadata.items() if k.startswith("ss_")}
|
82 |
+
model_bytes = safetensors.torch.save(tensors, metadata)
|
83 |
+
|
84 |
+
hash_sha256.update(model_bytes[0x100000:0x110000])
|
85 |
+
return hash_sha256.hexdigest()[0:8]
|
86 |
+
else:
|
87 |
+
# This should work fine with model_hash since when the legacy hashing
|
88 |
+
# method was being used the user metadata system hadn't been implemented
|
89 |
+
# yet.
|
90 |
+
return sd_models.model_hash(filename)
|
91 |
+
|
92 |
+
|
93 |
+
DTYPES = {
|
94 |
+
"F64": torch.float64,
|
95 |
+
"F32": torch.float32,
|
96 |
+
"F16": torch.float16,
|
97 |
+
"BF16": torch.bfloat16,
|
98 |
+
"I64": torch.int64,
|
99 |
+
# "U64": torch.uint64,
|
100 |
+
"I32": torch.int32,
|
101 |
+
# "U32": torch.uint32,
|
102 |
+
"I16": torch.int16,
|
103 |
+
# "U16": torch.uint16,
|
104 |
+
"I8": torch.int8,
|
105 |
+
"U8": torch.uint8,
|
106 |
+
"BOOL": torch.bool
|
107 |
+
}
|
108 |
+
|
109 |
+
|
110 |
+
def create_tensor(storage, info, offset):
|
111 |
+
"""Creates a tensor without holding on to an open handle to the parent model
|
112 |
+
file."""
|
113 |
+
dtype = DTYPES[info["dtype"]]
|
114 |
+
shape = info["shape"]
|
115 |
+
start, stop = info["data_offsets"]
|
116 |
+
return torch.asarray(storage[start + offset : stop + offset], dtype=torch.uint8).view(dtype=dtype).reshape(shape).clone().detach()
|
ex/additional-networks/scripts/util.py
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import csv
|
2 |
+
from io import StringIO
|
3 |
+
from typing import List
|
4 |
+
|
5 |
+
def split_path_list(path_list: str) -> List[str]:
|
6 |
+
pl = []
|
7 |
+
with StringIO() as f:
|
8 |
+
f.write(path_list)
|
9 |
+
f.seek(0)
|
10 |
+
for r in csv.reader(f):
|
11 |
+
pl += r
|
12 |
+
return pl
|
ex/additional-networks/scripts/xyz_grid_support.py
ADDED
@@ -0,0 +1,160 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import os.path
|
3 |
+
from modules import shared
|
4 |
+
import modules.scripts as scripts
|
5 |
+
from scripts import model_util, util
|
6 |
+
from scripts.model_util import MAX_MODEL_COUNT
|
7 |
+
|
8 |
+
|
9 |
+
LORA_TRAIN_METADATA_NAMES = {
|
10 |
+
"ss_session_id": "Session ID",
|
11 |
+
"ss_training_started_at": "Training started at",
|
12 |
+
"ss_output_name": "Output name",
|
13 |
+
"ss_learning_rate": "Learning rate",
|
14 |
+
"ss_text_encoder_lr": "Text encoder LR",
|
15 |
+
"ss_unet_lr": "UNet LR",
|
16 |
+
"ss_num_train_images": "# of training images",
|
17 |
+
"ss_num_reg_images": "# of reg images",
|
18 |
+
"ss_num_batches_per_epoch": "Batches per epoch",
|
19 |
+
"ss_num_epochs": "Total epochs",
|
20 |
+
"ss_epoch": "Epoch",
|
21 |
+
"ss_batch_size_per_device": "Batch size/device",
|
22 |
+
"ss_total_batch_size": "Total batch size",
|
23 |
+
"ss_gradient_checkpointing": "Gradient checkpointing",
|
24 |
+
"ss_gradient_accumulation_steps": "Gradient accum. steps",
|
25 |
+
"ss_max_train_steps": "Max train steps",
|
26 |
+
"ss_lr_warmup_steps": "LR warmup steps",
|
27 |
+
"ss_lr_scheduler": "LR scheduler",
|
28 |
+
"ss_network_module": "Network module",
|
29 |
+
"ss_network_dim": "Network dim",
|
30 |
+
"ss_network_alpha": "Network alpha",
|
31 |
+
"ss_mixed_precision": "Mixed precision",
|
32 |
+
"ss_full_fp16": "Full FP16",
|
33 |
+
"ss_v2": "V2",
|
34 |
+
"ss_resolution": "Resolution",
|
35 |
+
"ss_clip_skip": "Clip skip",
|
36 |
+
"ss_max_token_length": "Max token length",
|
37 |
+
"ss_color_aug": "Color aug",
|
38 |
+
"ss_flip_aug": "Flip aug",
|
39 |
+
"ss_random_crop": "Random crop",
|
40 |
+
"ss_shuffle_caption": "Shuffle caption",
|
41 |
+
"ss_cache_latents": "Cache latents",
|
42 |
+
"ss_enable_bucket": "Enable bucket",
|
43 |
+
"ss_min_bucket_reso": "Min bucket reso.",
|
44 |
+
"ss_max_bucket_reso": "Max bucket reso.",
|
45 |
+
"ss_seed": "Seed",
|
46 |
+
"ss_keep_tokens": "Keep tokens",
|
47 |
+
"ss_dataset_dirs": "Dataset dirs.",
|
48 |
+
"ss_reg_dataset_dirs": "Reg dataset dirs.",
|
49 |
+
"ss_sd_model_name": "SD model name",
|
50 |
+
"ss_vae_name": "VAE name",
|
51 |
+
"ss_training_comment": "Comment"
|
52 |
+
}
|
53 |
+
|
54 |
+
|
55 |
+
xy_grid = None # XY Grid module
|
56 |
+
script_class = None # additional_networks scripts.Script class
|
57 |
+
axis_params = [{}] * MAX_MODEL_COUNT
|
58 |
+
|
59 |
+
|
60 |
+
def update_axis_params(i, module, model):
|
61 |
+
axis_params[i] = {"module": module, "model": model}
|
62 |
+
|
63 |
+
|
64 |
+
def get_axis_model_choices(i):
|
65 |
+
module = axis_params[i].get("module", "None")
|
66 |
+
model = axis_params[i].get("model", "None")
|
67 |
+
|
68 |
+
if module == "LoRA":
|
69 |
+
if model != "None":
|
70 |
+
sort_by = shared.opts.data.get("additional_networks_sort_models_by", "name")
|
71 |
+
return model_util.get_model_list(module, model, "", sort_by)
|
72 |
+
|
73 |
+
return [f"select `Model {i+1}` in `Additional Networks`. models in same folder for selected one will be shown here."]
|
74 |
+
|
75 |
+
|
76 |
+
def update_script_args(p, value, arg_idx):
|
77 |
+
global script_class
|
78 |
+
for s in scripts.scripts_txt2img.alwayson_scripts:
|
79 |
+
if isinstance(s, script_class):
|
80 |
+
args = list(p.script_args)
|
81 |
+
# print(f"Changed arg {arg_idx} from {args[s.args_from + arg_idx - 1]} to {value}")
|
82 |
+
args[s.args_from + arg_idx] = value
|
83 |
+
p.script_args = tuple(args)
|
84 |
+
break
|
85 |
+
|
86 |
+
|
87 |
+
def confirm_models(p, xs):
|
88 |
+
for x in xs:
|
89 |
+
if x in ["", "None"]:
|
90 |
+
continue
|
91 |
+
if not model_util.find_closest_lora_model_name(x):
|
92 |
+
raise RuntimeError(f"Unknown LoRA model: {x}")
|
93 |
+
|
94 |
+
|
95 |
+
def apply_module(p, x, xs, i):
|
96 |
+
update_script_args(p, True, 0) # set Enabled to True
|
97 |
+
update_script_args(p, x, 2 + 4 * i) # enabled, separate_weights, ({module}, model, weight_unet, weight_tenc), ...
|
98 |
+
|
99 |
+
|
100 |
+
def apply_model(p, x, xs, i):
|
101 |
+
name = model_util.find_closest_lora_model_name(x)
|
102 |
+
update_script_args(p, True, 0)
|
103 |
+
update_script_args(p, name, 3 + 4 * i) # enabled, separate_weights, (module, {model}, weight_unet, weight_tenc), ...
|
104 |
+
|
105 |
+
|
106 |
+
def apply_weight(p, x, xs, i):
|
107 |
+
update_script_args(p, True, 0)
|
108 |
+
update_script_args(p, x, 4 + 4 * i ) # enabled, separate_weights, (module, model, {weight_unet, weight_tenc}), ...
|
109 |
+
update_script_args(p, x, 5 + 4 * i)
|
110 |
+
|
111 |
+
|
112 |
+
def apply_weight_unet(p, x, xs, i):
|
113 |
+
update_script_args(p, True, 0)
|
114 |
+
update_script_args(p, x, 4 + 4 * i) # enabled, separate_weights, (module, model, {weight_unet}, weight_tenc), ...
|
115 |
+
|
116 |
+
|
117 |
+
def apply_weight_tenc(p, x, xs, i):
|
118 |
+
update_script_args(p, True, 0)
|
119 |
+
update_script_args(p, x, 5 + 4 * i) # enabled, separate_weights, (module, model, weight_unet, {weight_tenc}), ...
|
120 |
+
|
121 |
+
|
122 |
+
def format_lora_model(p, opt, x):
|
123 |
+
global xy_grid
|
124 |
+
model = model_util.find_closest_lora_model_name(x)
|
125 |
+
if model is None or model.lower() in ["", "none"]:
|
126 |
+
return "None"
|
127 |
+
|
128 |
+
value = xy_grid.format_value(p, opt, model)
|
129 |
+
|
130 |
+
model_path = model_util.lora_models.get(model)
|
131 |
+
metadata = model_util.read_model_metadata(model_path, "LoRA")
|
132 |
+
if not metadata:
|
133 |
+
return value
|
134 |
+
|
135 |
+
metadata_names = util.split_path_list(shared.opts.data.get("additional_networks_xy_grid_model_metadata", ""))
|
136 |
+
if not metadata_names:
|
137 |
+
return value
|
138 |
+
|
139 |
+
for name in metadata_names:
|
140 |
+
name = name.strip()
|
141 |
+
if name in metadata:
|
142 |
+
formatted_name = LORA_TRAIN_METADATA_NAMES.get(name, name)
|
143 |
+
value += f"\n{formatted_name}: {metadata[name]}, "
|
144 |
+
|
145 |
+
return value.strip(" ").strip(",")
|
146 |
+
|
147 |
+
|
148 |
+
def initialize(script):
|
149 |
+
global xy_grid, script_class
|
150 |
+
xy_grid = None
|
151 |
+
script_class = script
|
152 |
+
for scriptDataTuple in scripts.scripts_data:
|
153 |
+
if os.path.basename(scriptDataTuple.path) == "xy_grid.py" or os.path.basename(scriptDataTuple.path) == "xyz_grid.py":
|
154 |
+
xy_grid = scriptDataTuple.module
|
155 |
+
for i in range(MAX_MODEL_COUNT):
|
156 |
+
model = xy_grid.AxisOption(f"AddNet Model {i+1}", str, lambda p, x, xs, i=i: apply_model(p, x, xs, i), format_lora_model, confirm_models, cost=0.5, choices=lambda i=i: get_axis_model_choices(i))
|
157 |
+
weight = xy_grid.AxisOption(f"AddNet Weight {i+1}", float, lambda p, x, xs, i=i: apply_weight(p, x, xs, i), xy_grid.format_value_add_label, None, cost=0.5)
|
158 |
+
weight_unet = xy_grid.AxisOption(f"AddNet UNet Weight {i+1}", float, lambda p, x, xs, i=i: apply_weight_unet(p, x, xs, i), xy_grid.format_value_add_label, None, cost=0.5)
|
159 |
+
weight_tenc = xy_grid.AxisOption(f"AddNet TEnc Weight {i+1}", float, lambda p, x, xs, i=i: apply_weight_tenc(p, x, xs, i), xy_grid.format_value_add_label, None, cost=0.5)
|
160 |
+
xy_grid.axis_options.extend([model, weight, weight_unet, weight_tenc])
|
ex/additional-networks/style.css
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#additional_networks_cover_image,
|
2 |
+
#additional_networks_cover_image > .h-60,
|
3 |
+
#additional_networks_cover_image > .h-60 > div,
|
4 |
+
#additional_networks_cover_image > .h-60 > div > img
|
5 |
+
{
|
6 |
+
height: 480px !important;
|
7 |
+
max-height: 480px !important;
|
8 |
+
min-height: 480px !important;
|
9 |
+
}
|
ex/dynamic-prompts/.eslintrc.js
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
module.exports = {
|
2 |
+
env: {
|
3 |
+
browser: true,
|
4 |
+
es2021: true,
|
5 |
+
},
|
6 |
+
extends: ["airbnb-base", "prettier"],
|
7 |
+
plugins: ["prettier"],
|
8 |
+
rules: {
|
9 |
+
"class-methods-use-this": "off",
|
10 |
+
"max-classes-per-file": "off",
|
11 |
+
"no-console": "off",
|
12 |
+
"no-param-reassign": "off",
|
13 |
+
"prettier/prettier": "error",
|
14 |
+
curly: ["error", "all"],
|
15 |
+
},
|
16 |
+
parserOptions: {
|
17 |
+
ecmaVersion: "latest",
|
18 |
+
},
|
19 |
+
};
|
ex/dynamic-prompts/.github/CONTRIBUTING.md
ADDED
@@ -0,0 +1,130 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# GitHub Etiquette
|
2 |
+
borrowed from [Open source etiquette](https://github.com/kossnocorp/opensource.how)
|
3 |
+
|
4 |
+
## Don't be mean!
|
5 |
+
|
6 |
+
Be nice!
|
7 |
+
|
8 |
+
## Don't be bossy!
|
9 |
+
|
10 |
+
It takes just a few seconds to type "Any updates on this?" but it takes much
|
11 |
+
more time and energy to write a report back to you. First of all, you're not
|
12 |
+
maintainers' boss, and they owe you nothing, not to mention a report.
|
13 |
+
|
14 |
+
These minutes could have been spent on something meaningful, so you not only
|
15 |
+
steal time from the maintainer, but also the whole community.
|
16 |
+
|
17 |
+
Don't write like a boss: "Why this isn't merged?" "What's the ETA?" "It blocks
|
18 |
+
us!" "What are the blockers?".
|
19 |
+
|
20 |
+
## Don't demand!
|
21 |
+
|
22 |
+
Never demand anything from maintainers. Always keep in mind that maintainers'
|
23 |
+
work is an act of goodwill — even labor backed by the community rarely pays
|
24 |
+
more than minimum wage, so communicate accordingly.
|
25 |
+
|
26 |
+
If you need a piece of information or help, say it politely. If you want to
|
27 |
+
have something done, never push.
|
28 |
+
|
29 |
+
First of all, you could have different priorities. You and your colleagues
|
30 |
+
might be aligned on the same goal, but maintainers can have a different focus.
|
31 |
+
Secondly, you might have a different perspective on the problem. Be ready to
|
32 |
+
accept a rejection of your proposal, feature, or bug report. Yes, sometimes,
|
33 |
+
bugs are features!
|
34 |
+
|
35 |
+
## Don't be noisy!
|
36 |
+
|
37 |
+
Comments like "I also have this error" and "+1" are never helpful. It's
|
38 |
+
especially tempting to type such comment when it's a critical issue, but that
|
39 |
+
adds additional pressure and distraction.
|
40 |
+
|
41 |
+
If you want the get the attention of the maintainer, at least contribute
|
42 |
+
something. If the issue lacks stack trace or reproductions steps, add it.
|
43 |
+
Don't feel capable of opening a PR? Create a minimal repo with the demo of the
|
44 |
+
error.
|
45 |
+
|
46 |
+
## Don't rush!
|
47 |
+
|
48 |
+
Take your time before reporting a bug or asking a question. First, make sure
|
49 |
+
you're not missing anything. Read the docs, Google the problem, search the
|
50 |
+
issues, double-check, and only then reach for help.
|
51 |
+
|
52 |
+
When you do reach for help, make sure that you provide as much information as
|
53 |
+
possible. Proactively present library versions, code example, reproduction
|
54 |
+
steps, etc. Describe the problem in detail. Don't wait for the maintainers to
|
55 |
+
ask you for that. Provide or at least offer to provide a minimal reproducible
|
56 |
+
example. This way, you'll minimize the effort that they have to put to help
|
57 |
+
you, which would maximize your chances to prompt response.
|
58 |
+
|
59 |
+
It's easy for you to assume that all they need is a short description of the
|
60 |
+
problem as the maintainers know their thing the best and provide additional
|
61 |
+
information only when they ask you. But in that's just a time steal and the
|
62 |
+
best way to get rightfully ignored.
|
63 |
+
|
64 |
+
## Don't be emotional!
|
65 |
+
|
66 |
+
When the deadline is approaching and you still have a lot to do, a bug or
|
67 |
+
unexpected behavior in the code you don't control is annoyance at least. Never
|
68 |
+
show it!
|
69 |
+
|
70 |
+
The maintainer has a different perspective and might not be aware of the
|
71 |
+
problem even if you feel like everything is broken. If you want to get help,
|
72 |
+
then be calm, objective, and patient.
|
73 |
+
|
74 |
+
## Don't patronize!
|
75 |
+
|
76 |
+
Never assume that the maintainer is less experienced or knowledgeable or
|
77 |
+
straight stupid. That better approach, tool, or decision that you have in mind
|
78 |
+
might have been considered or even planned. They have full context and had
|
79 |
+
much more time than you to think everything through, so more likely, it's you
|
80 |
+
who's confused.
|
81 |
+
|
82 |
+
It's reasonable to think that the maintainer is an expert in the subject, and
|
83 |
+
you're not. Even if you find an objectively low-quality code, don't assume the
|
84 |
+
authors' experience or skills.
|
85 |
+
|
86 |
+
If you disagree with the direction, instead of arguing, it's better to
|
87 |
+
consider an alternative. Some prefer functional programming, some
|
88 |
+
object-oriented code, but that doesn't mean that latter or former are wrong.
|
89 |
+
The maintainer should be able to decide what trade-off to choose regardless of
|
90 |
+
your needs or views.
|
91 |
+
|
92 |
+
## Don't forget to say thanks!
|
93 |
+
|
94 |
+
Simple words of gratitude and praises are often the sole motivator that makes
|
95 |
+
open-source authors keep going, so don't be shy and say it!
|
96 |
+
|
97 |
+
Do you want to see a pull-request merged, much-needed feature implemented and
|
98 |
+
long-awaiter release shipped? Instead of reminding how much work is on their
|
99 |
+
plate by asking "any news" or showing dissatisfaction (which only kills the
|
100 |
+
motivation), say how their work is essential. Tell how much you value them.
|
101 |
+
Tweet kind words about them and their project. Sometimes that's the best you
|
102 |
+
can do.
|
103 |
+
|
104 |
+
## Don't cause drama!
|
105 |
+
|
106 |
+
Never post comments that might cause a drama or emotionally hurt maintainers.
|
107 |
+
|
108 |
+
You might be upset about maintainers intrusively asking for donations. You
|
109 |
+
might be frustrated by the lack of attention to your issue. You might be
|
110 |
+
dissatisfied with the quality of the project. You might know the better
|
111 |
+
alternative. You might think that's enough for you to post a comment demanding
|
112 |
+
to remove annoying ads or announce that you're moving to another solution. No,
|
113 |
+
it's not.
|
114 |
+
|
115 |
+
For you, that would be a simple message, but on another end, it might ruin the
|
116 |
+
day or strip out the motivation to continue. That's not the right way to treat
|
117 |
+
people that decided to give something for you for free, even if it's not good
|
118 |
+
enough.
|
119 |
+
|
120 |
+
## Don't surprise!
|
121 |
+
|
122 |
+
If you plan to contribute great work to a project, communicate it first. Your
|
123 |
+
vision might differ from the maintainers' one, or it could collide with their
|
124 |
+
plans or ongoing work. The worst way you could help them is to create more
|
125 |
+
work.
|
126 |
+
|
127 |
+
If you get rejected, be understanding and not try to cause the feeling of
|
128 |
+
guilt. It's already hard for maintainers to say no, so don't make it harder.
|
129 |
+
Feel free to clarify your intention if you think they misunderstood you but
|
130 |
+
never start an argument.
|
ex/dynamic-prompts/.github/ISSUE_TEMPLATE/bug_report.md
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
**Before opening a new issue**
|
3 |
+
|
4 |
+
Make sure that you have had a look at the [troubleshooting section](https://github.com/adieyal/sd-dynamic-prompts#troubleshooting) of the project's README file.
|
5 |
+
|
6 |
+
**Describe the bug**
|
7 |
+
|
8 |
+
A clear and concise description of what the bug is.
|
9 |
+
|
10 |
+
**To Reproduce**
|
11 |
+
Steps to reproduce the behaviour, include the prompt you used if applicable:
|
12 |
+
1. Go to '...'
|
13 |
+
2. Click on '....'
|
14 |
+
3. Scroll down to '....'
|
15 |
+
4. See error
|
16 |
+
|
17 |
+
Also mention which checkboxes have been set.
|
18 |
+
|
19 |
+
**What version of the extension and dynamicprompts library do you have installed?**
|
20 |
+
|
21 |
+
These can be found under the Need Help? accordion.
|
22 |
+
|
23 |
+
**Are you using a local install or a colab?**
|
24 |
+
|
25 |
+
If a colab, which one?
|
26 |
+
|
27 |
+
**Expected behaviour**
|
28 |
+
A clear and concise description of what you expected to happen.
|
29 |
+
|
30 |
+
**Additional context**
|
31 |
+
Add any other context about the problem here.
|
ex/dynamic-prompts/.github/workflows/test.yml
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: Test
|
2 |
+
|
3 |
+
on:
|
4 |
+
push:
|
5 |
+
branches:
|
6 |
+
- main
|
7 |
+
pull_request:
|
8 |
+
branches:
|
9 |
+
- main
|
10 |
+
|
11 |
+
jobs:
|
12 |
+
lint:
|
13 |
+
runs-on: ubuntu-latest
|
14 |
+
steps:
|
15 |
+
- uses: actions/checkout@v3
|
16 |
+
- uses: pre-commit/action@v3.0.0
|
17 |
+
test:
|
18 |
+
runs-on: ubuntu-latest
|
19 |
+
steps:
|
20 |
+
- uses: actions/checkout@v3
|
21 |
+
- name: Set up Python ${{ matrix.python-version }}
|
22 |
+
uses: actions/setup-python@v4
|
23 |
+
with:
|
24 |
+
python-version: "3.10"
|
25 |
+
cache: "pip"
|
26 |
+
- name: Install dependencies
|
27 |
+
run: python -m pip install pytest-cov -r requirements.txt
|
28 |
+
- run: pytest --cov --cov-report=term-missing .
|
ex/dynamic-prompts/.gitignore
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
*.pyc
|
2 |
+
.coverage
|
3 |
+
.env
|
4 |
+
.vscode
|
5 |
+
\.*.sw*
|
6 |
+
node_modules
|
7 |
+
wildcards
|
ex/dynamic-prompts/.pre-commit-config.yaml
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
repos:
|
2 |
+
- repo: https://github.com/charliermarsh/ruff-pre-commit
|
3 |
+
rev: v0.0.259
|
4 |
+
hooks:
|
5 |
+
- id: ruff
|
6 |
+
args:
|
7 |
+
- --fix
|
8 |
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
9 |
+
rev: v4.4.0
|
10 |
+
hooks:
|
11 |
+
- id: end-of-file-fixer
|
12 |
+
exclude: ^collections/.*
|
13 |
+
- id: trailing-whitespace
|
14 |
+
exclude: ^collections/.*
|
15 |
+
- repo: https://github.com/psf/black
|
16 |
+
rev: 23.1.0
|
17 |
+
hooks:
|
18 |
+
- id: black
|
19 |
+
args:
|
20 |
+
- --quiet
|
ex/dynamic-prompts/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
MIT License
|
2 |
+
|
3 |
+
Copyright (c) 2022 Adi Eyal
|
4 |
+
|
5 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6 |
+
of this software and associated documentation files (the "Software"), to deal
|
7 |
+
in the Software without restriction, including without limitation the rights
|
8 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9 |
+
copies of the Software, and to permit persons to whom the Software is
|
10 |
+
furnished to do so, subject to the following conditions:
|
11 |
+
|
12 |
+
The above copyright notice and this permission notice shall be included in all
|
13 |
+
copies or substantial portions of the Software.
|
14 |
+
|
15 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21 |
+
SOFTWARE.
|
ex/dynamic-prompts/README.md
ADDED
@@ -0,0 +1,325 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Stable Diffusion Dynamic Prompts extension
|
2 |
+
A custom extension for [AUTOMATIC1111/stable-diffusion-webui](https://github.com/AUTOMATIC1111/stable-diffusion-webui) that implements an expressive template language for random or combinatorial prompt generation along with features to support deep wildcard directory structures.
|
3 |
+
|
4 |
+
<p align="center">
|
5 |
+
<a href="docs/SYNTAX.md"><img src="images/icon-syntax.png" valign="middle" style="height:60px;margin-right:10px"/></a>
|
6 |
+
<a href="docs/tutorial.md"><img src="images/icon-tutorial.png" valign="middle" style="height:60px;margin-right:10px"/></a>
|
7 |
+
<a href="docs/CHANGELOG.md"><img src="images/icon-changelog.png" valign="middle" style="height:60px"/></a>
|
8 |
+
</p>
|
9 |
+
|
10 |
+
<img src="images/extension.png"/>
|
11 |
+
|
12 |
+
## Table of Contents
|
13 |
+
|
14 |
+
* [Basic Usage](#basic-usage)
|
15 |
+
* [Online resources](#online-resources)
|
16 |
+
* [Installation](#installation)
|
17 |
+
* [Configuration](#configuration)
|
18 |
+
* [Troubleshooting](#troubleshooting)
|
19 |
+
* [Compatible Scripts](#compatible-scripts)
|
20 |
+
* [Template syntax](#template-syntax)
|
21 |
+
* [Fuzzy Glob/recursive wildcard file/directory matching](#fuzzy-globrecursive-wildcard-filedirectory-matching)
|
22 |
+
* [Combinatorial Generation](#combinatorial-generation)
|
23 |
+
* [Combinatorial Batches](#combinatorial-batches)
|
24 |
+
* [Increasing the maximum number of generations](#increasing-the-maximum-number-of-generations)
|
25 |
+
* [Fixed seed](#fixed-seed)
|
26 |
+
* [Magic Prompt](#magic-prompt)
|
27 |
+
* [Other models](#other-models)
|
28 |
+
* [I'm feeling lucky](#im-feeling-lucky)
|
29 |
+
* [Attention grabber](#attention-grabber)
|
30 |
+
* [Write prompts to file](#write-prompts-to-file)
|
31 |
+
* [Jinja2 templates](#jinja2-templates)
|
32 |
+
* [WILDCARD_DIR](#wildcard_dir)
|
33 |
+
* [Collections](#collections)
|
34 |
+
* [Dynamic Prompts and Random Seeds](#dynamic-prompts-and-random-seeds)
|
35 |
+
* [Without Dynamic Prompts Enabled](#without-dynamic-prompts-enabled)
|
36 |
+
* [With Dynamic Prompts Enabled in Random/Standard Mode](#with-dynamic-prompts-enabled-in-randomstandard-mode)
|
37 |
+
* [Variation Seeds with Dynamic Prompts](#variation-seeds-with-dynamic-prompts)
|
38 |
+
* [Combinatorial Mode with Variation Strength > 0](#combinatorial-mode-with-variation-strength--0)
|
39 |
+
|
40 |
+
|
41 |
+
## Basic Usage
|
42 |
+
Using this script, the prompt:
|
43 |
+
|
44 |
+
A {house|apartment|lodge|cottage} in {summer|winter|autumn|spring} by {2$$artist1|artist2|artist3}
|
45 |
+
|
46 |
+
Will produce any of the following prompts:
|
47 |
+
|
48 |
+
- A **house** in **summer** by **artist1**, **artist2**
|
49 |
+
- A **lodge** in **autumn** by **artist3**, **artist1**
|
50 |
+
- A **cottage** in **winter** by **artist2**, **artist3**
|
51 |
+
- ...
|
52 |
+
|
53 |
+
This is especially useful if you are searching for interesting combinations of artists and styles.
|
54 |
+
|
55 |
+
You can also pick a random string from a file. Assuming you have the file seasons.txt in WILDCARD_DIR (see below), then:
|
56 |
+
|
57 |
+
__seasons__ is coming
|
58 |
+
|
59 |
+
Might generate the following:
|
60 |
+
|
61 |
+
- Winter is coming
|
62 |
+
- Spring is coming
|
63 |
+
- ...
|
64 |
+
|
65 |
+
You can also use the same wildcard twice
|
66 |
+
|
67 |
+
I love __seasons__ better than __seasons__
|
68 |
+
|
69 |
+
- I love Winter better than Summer
|
70 |
+
- I love Spring better than Spring
|
71 |
+
|
72 |
+
More complete documentation can be found [here](docs/SYNTAX.md).<br/>
|
73 |
+
Prefer a tutorial? <a href="docs/tutorial.md">Click here</a><br/>
|
74 |
+
Need a wildcard library? We've got you [covered](https://github.com/adieyal/sd-dynamic-prompts#collections).<br/>
|
75 |
+
|
76 |
+
## Online resources
|
77 |
+
* 📽️ [아무것도 생각 안 하고 그림 뽑는 방법 (stable diffusion Dynamic Prompts extension)](https://www.youtube.com/watch?v=5wH7zioje4w)
|
78 |
+
* 📽️ [Dynamic Prompt Tutorial: How to Create Multiple Art Variations with just 1 Prompt Stable Diffusion](https://www.youtube.com/watch?v=5wH7zioje4w)
|
79 |
+
* 📽️ [Experiment with Prompts FAST in Stable Diffusion](https://www.youtube.com/watch?v=5ZiL4iG0FJk)
|
80 |
+
* [Having a blast with ControlNet + Dynamic Prompts (Wildcards)](https://www.reddit.com/r/StableDiffusion/comments/115t0pi/having_a_blast_with_controlnet_dynamic_prompts/)
|
81 |
+
* [Infinite Random RPG Character Portraits with Dynamic Prompts](https://www.reddit.com/r/StableDiffusion/comments/10xqwjm/i_come_bearing_gifts_infinite_random_rpg/)
|
82 |
+
* [256 unique characters created with dynamic prompts ](https://www.reddit.com/r/StableDiffusion/comments/106hxm1/256_unique_characters_created_with_dynamic/)
|
83 |
+
* [Use ChatGPT to create powerful and useful wildcards with the Dynamic Prompts extension](https://www.reddit.com/r/StableDiffusion/comments/10m6b4a/use_chatgpt_to_create_powerful_and_useful/)
|
84 |
+
* [200 Character/outfit designs from a single prompt using Dynamic Prompts and Prompt Editing](https://www.reddit.com/r/StableDiffusion/comments/1080xyy/200_characteroutfit_designs_from_a_single_prompt/)
|
85 |
+
* [Dynamic Prompts and Jinja2 templates in Automatic 1111](https://www.reddit.com/r/StableDiffusion/comments/10jgmtk/dynamic_prompts_and_jinja2_templates_in_automatic/)
|
86 |
+
* [Testing Dynamic Prompts extension to mix and match elements](https://www.reddit.com/r/StableDiffusion/comments/10gkm1c/testing_dynamic_prompts_extension_to_mix_and/)
|
87 |
+
* [How to Turbocharge your prompts using AUTOMATIC1111 WebUI dynamic prompts extension](https://www.reddit.com/r/StableDiffusion/comments/ynztiz/how_to_turbocharge_your_prompts_using/)
|
88 |
+
* [Dynamic prompts for Automatic1111 is so incredibly powerful, these are all from the same prompt!](https://www.reddit.com/r/StableDiffusion/comments/zacjhk/dynamic_prompts_for_automatic1111_is_so/)
|
89 |
+
|
90 |
+
## Installation
|
91 |
+
|
92 |
+
The extension can be installed directly from within the **Extensions** tab within the Webui
|
93 |
+
<img src="images/installation.png"/>
|
94 |
+
|
95 |
+
You can also install it manually by running the following command from within the webui directory:
|
96 |
+
|
97 |
+
git clone https://github.com/adieyal/sd-dynamic-prompting/ extensions/dynamic-prompts
|
98 |
+
|
99 |
+
## Configuration
|
100 |
+
In case of a syntax clash with another extension, Dynamic Prompts allows you to change the definition of variant start and variant end. By default these are set to `{` and `}` respectively. , e.g. `{red|green|blue}`. In the settings tab, you can change these two any string, e.g. `<red|green|blue>` or even `::red|green|blue::`.
|
101 |
+
|
102 |
+
<img src="images/config_brackets.png">
|
103 |
+
|
104 |
+
By default, wildcards start with `__`(double underscore) and end with `__`. You can change this in the settings tab under wildcard wrap.
|
105 |
+
|
106 |
+
## Troubleshooting
|
107 |
+
If you encounter an issue with Dynamic Prompts, follow these steps to resolve the problem:
|
108 |
+
|
109 |
+
1. Check that you have installed the latest version of both the Dynamic Prompts extension and library. To check the installed versions, open the **Need Help? accordion** in the Dynamic Prompts section of txt2image. You can find the latest version number of the extension [here](https://github.com/adieyal/sd-dynamic-prompts/blob/main/docs/CHANGELOG.md) and the library [here](https://github.com/adieyal/dynamicprompts/blob/main/CHANGELOG.md?plain=1).
|
110 |
+
|
111 |
+
2. If the versions do not match, update the extension in the extensions tab and restart the webui. The extension should automatically update the library.
|
112 |
+
|
113 |
+
3. If the above step does not work, you might need to manually update the library using the following command:
|
114 |
+
|
115 |
+
```shell
|
116 |
+
python -m pip install -U dynamicprompts[attentiongrabber,magicprompt]
|
117 |
+
```
|
118 |
+
|
119 |
+
4. Restart the webui and check. If the webui uses a different python binary, find the correct path to the python binary and run:
|
120 |
+
|
121 |
+
```shell
|
122 |
+
/path/to/python/binary/python -m pip install -U dynamicprompts[attentiongrabber,magicprompt]
|
123 |
+
```
|
124 |
+
|
125 |
+
5. If the Wildcard UI does not show, it could be due to an outdated library version. Check for errors in the terminal and update the library as described in step 3.
|
126 |
+
|
127 |
+
6. If you get an error message saying "No values found for wildcard some/wildcard", ensure that the file wildcard.txt is in extensions/sd-dynamic-prompts/wildcards/some/. The full path is required, as relative paths are not currently supported.
|
128 |
+
|
129 |
+
7. If the issue persists, search for solutions in the [issues section](https://github.com/adieyal/sd-dynamic-prompts/issues?q=is%3Aissue) on Github and the [discussion forum](https://github.com/adieyal/sd-dynamic-prompts/discussions). If you cannot find a solution, create a new issue and give it a descriptive name, such as "Wildcard values are being ignored in prompt templates". Provide the necessary context, including the versions of the Dynamic Prompts extension and library, and mention the operating system or colab being used. If there is an error in the terminal, copy and paste the entire text or take a screenshot.
|
130 |
+
|
131 |
+
8. Finally, it is essential to test and apply any fixes we release. Your feedback is valuable, as an issue that works in our environment may not work in yours.
|
132 |
+
|
133 |
+
## Compatible Scripts
|
134 |
+
Dynamic Prompts works particularly well with X/Y Plot - setting Dynamic Prompts to <a href="#combinatorial-generation">combinatorial mode</a> while using X/Y Plot, lets you exhaustively test prompt and paramter variations simultaneously.
|
135 |
+
|
136 |
+
|
137 |
+
## Template syntax
|
138 |
+
Documentation can be found [here](docs/SYNTAX.md)
|
139 |
+
|
140 |
+
### Fuzzy Glob/recursive wildcard file/directory matching
|
141 |
+
In addition to standard wildcard tokens such as `__times__` -> `times.txt`, you can also use globbing to match against multiple files at once.
|
142 |
+
For instance:
|
143 |
+
|
144 |
+
`__colors*__` will match any of the following:
|
145 |
+
- WILDCARD_DIR/colors.txt
|
146 |
+
- WILDCARD_DIR/colors1.txt
|
147 |
+
- WILDCARD_DIR/nested/folder/colors1.txt
|
148 |
+
|
149 |
+
`__light/**/*__` will match:
|
150 |
+
- WILDCARD_DIR/nested/folder/light/a.txt
|
151 |
+
- WILDCARD_DIR/nested/folder/light/b.txt
|
152 |
+
|
153 |
+
but won't match
|
154 |
+
- WILDCARD_DIR/nested/folder/dark/a.txt
|
155 |
+
- WILDCARD_DIR/a.txt
|
156 |
+
|
157 |
+
You can also used character ranges `[0-9]` and `[a-z]` and single wildcard characters `?`. For more examples see [this article](http://pymotw.com/2/glob/).
|
158 |
+
|
159 |
+
## Combinatorial Generation
|
160 |
+
Instead of generating random prompts from a template, combinatorial generation produced every possible prompt from the given string. For example:
|
161 |
+
`I {love|hate} {New York|Chicago} in {June|July|August}`
|
162 |
+
|
163 |
+
will produce:
|
164 |
+
- I love New York in June
|
165 |
+
- I love New York in July
|
166 |
+
- I love New York in August
|
167 |
+
- I love Chicago in June
|
168 |
+
- I love Chicago in July
|
169 |
+
- I love Chicago in August
|
170 |
+
- I hate New York in June
|
171 |
+
- I hate New York in July
|
172 |
+
- I hate New York in August
|
173 |
+
- I hate Chicago in June
|
174 |
+
- I hate Chicago in July
|
175 |
+
- I hate Chicago in August
|
176 |
+
|
177 |
+
If a `__wildcard__` is provided, then a new prompt will be produced for every value in the wildcard file. For example:
|
178 |
+
`My favourite season is __seasons__`
|
179 |
+
|
180 |
+
will produce:
|
181 |
+
- My favourite season is Summer
|
182 |
+
- My favourite season is August
|
183 |
+
- My favourite season is Winter
|
184 |
+
- My favourite season is Sprint
|
185 |
+
|
186 |
+
<img src="images/combinatorial_generation.png"/>
|
187 |
+
|
188 |
+
You also arbitrarily nest combinations inside wildcards and wildcards in combinations.
|
189 |
+
|
190 |
+
Combinatorial generation can be useful if you want to create an image for every artist in a file. It can be enabled by checking the __Combinatorial generation__ checkbox in the ui. In order to prevent accidentially producing thousands of images, you can limit the total number of prompts generated using the **Max Generations** slider. A value of 0 (the default) will not set any limit.
|
191 |
+
|
192 |
+
### Combinatorial Batches
|
193 |
+
The combinatorial batches slider lets you repeat the same set of prompts a number of times with different seeds. The default number of batches is 1.
|
194 |
+
|
195 |
+
### Increasing the maximum number of generations
|
196 |
+
By default, the __Batch count__ silder of automatic1111 has a maximum value of 100. This can limit the maximum number of generations when using combinatorial generation. You can change the maximum value of this slider by editing ui-config.json and change:
|
197 |
+
|
198 |
+
txt2img/Batch count/maximum": 100
|
199 |
+
|
200 |
+
to something larger like:
|
201 |
+
|
202 |
+
txt2img/Batch count/maximum": 1000
|
203 |
+
|
204 |
+
## Fixed seed
|
205 |
+
Select this if you want to use the same seed for every generated image. If there are no wildcards then all the images will be identical. It is useful if you want to test the effect of a particular modifier. For example:
|
206 |
+
|
207 |
+
A beautiful day at the beach __medium/photography/filmtypes__
|
208 |
+
|
209 |
+
That way you can isolate the effect of each film type on a particular scene. Here are some of the results:
|
210 |
+
<img src="images/filmtypes.jpg"/>
|
211 |
+
|
212 |
+
## Magic Prompt
|
213 |
+
Use one of a number of prompt generation models to spice up your prompt.
|
214 |
+
|
215 |
+
Using [Gustavosta](https://huggingface.co/Gustavosta/MagicPrompt-Stable-Diffusion)'s MagicPrompt model, Trained on 80,000 prompts from [Lexica.art](lexica.art), it can help give you interesting new prompts on a given subject. Here are some automatically generated variations for "dogs playing football":
|
216 |
+
|
217 |
+
> dogs playing football, in the streets of a japanese town at night, with people watching in wonder, in the style of studio ghibli and makoto shinkai, highly detailed digital art, trending on artstation
|
218 |
+
|
219 |
+
> dogs playing football, in the background is a nuclear explosion. photorealism. hq. hyper. realistic. 4 k. award winning.
|
220 |
+
|
221 |
+
> dogs playing football, in the background is a nuclear explosion. photorealistic. realism. 4 k wideshot. cinematic. unreal engine. artgerm. marc simonetti. jc leyendecker
|
222 |
+
|
223 |
+
This is compatible with the wildcard syntax described above.
|
224 |
+
|
225 |
+
### Other models
|
226 |
+
* [daspartho/prompt-extend (~500mb)](https://huggingface.co/daspartho/prompt-extend)
|
227 |
+
* [succinctly/text2image-prompt-generator (~600mb)](https://huggingface.co/succinctly/text2image-prompt-generator) - Trained on Midjourney prompts
|
228 |
+
* [microsoft/Promptist (~500mb)](https://huggingface.co/microsoft/Promptist) - Read the paper [here](https://arxiv.org/abs/2212.09611)
|
229 |
+
* [AUTOMATIC/promptgen-lexart (~300mb)](https://huggingface.co/AUTOMATIC/promptgen-lexart) - Finetuned using 134,819 prompts from lexica.art
|
230 |
+
* [AUTOMATIC/promptgen-majinai-safe (~300mb)](https://huggingface.co/AUTOMATIC/promptgen-majinai-safe) - 1,654 prompts from majinai.art
|
231 |
+
* [AUTOMATIC/promptgen-majinai-unsafe (~300mb)](https://huggingface.co/AUTOMATIC/promptgen-majinai-unsafe) - 825 prompts from majinai.art (NSFW)
|
232 |
+
* [Gustavosta/MagicPrompt-Dalle](https://huggingface.co/Gustavosta/MagicPrompt-Dalle)
|
233 |
+
* [kmewhort/stable-diffusion-prompt-bolster (~500mb)](https://huggingface.co/kmewhort/stable-diffusion-prompt-bolster),
|
234 |
+
* [Ar4ikov/gpt2-650k-stable-diffusion-prompt-generator (~500mb)](Ar4ikov/gpt2-650k-stable-diffusion-prompt-generator),
|
235 |
+
* [Ar4ikov/gpt2-medium-650k-stable-diffusion-prompt-generator (~1.4gb)](https://huggingface.co/Ar4ikov/gpt2-medium-650k-stable-diffusion-prompt-generator),
|
236 |
+
* [crumb/bloom-560m-RLHF-SD2-prompter-aesthetic (~1.1gb)](https://huggingface.co/crumb/bloom-560m-RLHF-SD2-prompter-aesthetic),
|
237 |
+
* [Meli/GPT2-Prompt (~500mb)](https://huggingface.co/Meli/GPT2-Prompt),
|
238 |
+
* [DrishtiSharma/StableDiffusion-Prompt-Generator-GPT-Neo-125M (~550mb)](https://huggingface.co/DrishtiSharma/StableDiffusion-Prompt-Generator-GPT-Neo-125M)
|
239 |
+
|
240 |
+
The first time you use a model, it is downloaded. It is approximately 500mb and so will take some time depending on how fast your connection is. It will also take a few seconds on first activation as the model is loaded into memory. Note, if you're low in VRAM, you might get a Cuda error. My GPU uses less than 8GB but YMMV.
|
241 |
+
|
242 |
+
<img src="images/magic_prompt.png"/>
|
243 |
+
|
244 |
+
|
245 |
+
You can control the maximum prompt length with the __Max magic prompt length__ slider. __Magic prompt creativity__ can adjust the generated prompt but you will need to experiment with this setting.
|
246 |
+
|
247 |
+
Use the __Magic prompt blocklist regex__ to filter out keywords. For example, if you want to avoid prompts containing Greg Rutkowski, add his name to this field.
|
248 |
+
|
249 |
+
If you are generating many prompts using Magic Prompt, then increasing the __Magic Prompt batch size__ can improve significantly improve prompt generation speed. This may only be noticeable if you are not generating images as well since image generation is much slower than prompt generation.
|
250 |
+
|
251 |
+
|
252 |
+
## I'm feeling lucky
|
253 |
+
Use the [lexica.art](https://lexica.art) API to create random prompts. Useful if you're looking for inspiration, or are simply too lazy to think of your own prompts. When this option is selected, the prompt in the main prompt box is used as a search string. For example, prompt "Mech warrior" might return:
|
254 |
+
|
255 |
+
* A large robot stone statue in the middle of a forest by Greg Rutkowski, Sung Choi, Mitchell Mohrhauser, Maciej Kuciara, Johnson Ting, Maxim Verehin, Peter Konig, final fantasy , 8k photorealistic, cinematic lighting, HD, high details, atmospheric,
|
256 |
+
* a beautiful portrait painting of a ( ( ( cyberpunk ) ) ) armor by simon stalenhag and pascal blanche and alphonse mucha and nekro. in style of digital art. colorful comic, film noirs, symmetry, brush stroke, vibrating colors, hyper detailed. octane render. trending on artstation
|
257 |
+
* symmetry!! portrait of a robot astronaut, floral! horizon zero dawn machine, intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha, 8 k
|
258 |
+
|
259 |
+
<img src="images/feeling-lucky.png">
|
260 |
+
|
261 |
+
Leaving the prompt box blank returns a list of completely randomly chosen prompts.
|
262 |
+
|
263 |
+
## Attention grabber
|
264 |
+
This option randomly selects a keyword in your prompt and adds a random amount of emphasis. Below is an example of how this affects the prompt:
|
265 |
+
|
266 |
+
a portrait an anthropomorphic panda mage casting a spell, wearing mage robes, landscape in background, cute, dnd character art portrait, by jason felix and peter mohrbacher, cinematic lighting
|
267 |
+
|
268 |
+
<img src="images/emphasis.png">
|
269 |
+
|
270 |
+
Tick the __Fixed seed__ checkbox under __Advanced options__ to see how emphasis changes your image without changing seed.
|
271 |
+
|
272 |
+
|
273 |
+
## Write prompts to file
|
274 |
+
Check the write prompts to file checkbox in order to create a file with all generated prompts. The generated file is a slugified version of the prompt and can be found in the same directory as the generated images, e.g. outputs/txt2img-images
|
275 |
+
<img src="images/write_prompts.png"/>
|
276 |
+
|
277 |
+
## Jinja2 templates
|
278 |
+
[Jinja2 templates](https://jinja.palletsprojects.com/en/3.1.x/templates/) is an experimental feature that enables you to define prompts imperatively. This is an advanced feature and is only recommended for users who are comfortable writing scripts.
|
279 |
+
|
280 |
+
To enable, open the advanced accordion and select __Enable Jinja2 templates__.
|
281 |
+
<img src="images/jinja_templates.png">
|
282 |
+
|
283 |
+
You can read about them in more detail <a href="jinja2.md">here</a>
|
284 |
+
|
285 |
+
## WILDCARD_DIR
|
286 |
+
The extension looks for wildcard files in WILDCARD_DIR. The default location is /path/to/stable-diffusion-webui/extensions/sd-dynamic-prompts/wildcards. It can also be manually defined in the main webui config.json under wildcard_dir. When in doubt, the help text for the extension in the webui lists the full path to WILDCARD_DIR
|
287 |
+
|
288 |
+
## Collections
|
289 |
+
The collections directory contains modifier libraries that you can use as is or to bootstrap your own. To get started, either use the Wildcard Manager tab to copy a one or more collections to your wildcards folder, or you can manually copy the files across. There are currently three collections:
|
290 |
+
|
291 |
+
- [jumbo](https://github.com/adieyal/sd-dynamic-prompts/tree/main/collections/jumbo)
|
292 |
+
- [parrotzone](https://github.com/adieyal/sd-dynamic-prompts/tree/main/collections/parrotzone)
|
293 |
+
- [devilkkw](https://github.com/adieyal/sd-dynamic-prompts/tree/main/collections/devilkkw)
|
294 |
+
|
295 |
+
Jumbo is a very large collection of wildcards across many categories including aesthetics, appearance, artists, medium, style, and time. It is a work in progress, but aims to provide good coverage of various modifier categories.
|
296 |
+
|
297 |
+
Parrotzone is a far smaller and more manageable collection sourced from https://proximacentaurib.notion.site/e28a4f8d97724f14a784a538b8589e7d?v=42948fd8f45c4d47a0edfc4b78937474.
|
298 |
+
|
299 |
+
Devilkkw focuses more on character building, clothes, gestures, food, etc
|
300 |
+
|
301 |
+
If you're using a Unix/Linux O/S, you can easily create a symlink to the relevant collection rather than copying it across if you don't plan to alter it. E.g.
|
302 |
+
|
303 |
+
ln -sr collections/parrotzone wildcards/
|
304 |
+
|
305 |
+
## Dynamic Prompts and Random Seeds
|
306 |
+
Random seeds play an important role in controlling the randomness of the generated outputs. Let's discuss how Dynamic Prompts works with random seeds in different scenarios.
|
307 |
+
|
308 |
+
### Without Dynamic Prompts Enabled
|
309 |
+
!. Seed set to -1: A random seed is selected, the first image is generated using that seed, the next image is generated with that seed + 1, and so on.
|
310 |
+
2. Seed set to a number > -1: The process is the same as above, but the seed used is the one chosen.
|
311 |
+
3. Variation seed set but variation strength is set to zero: The situation is the same as the previous two scenarios.
|
312 |
+
4. Variation seed set to a number > 0: All images are created using the same seed (either randomly chosen or set by the user). The variation seed is either chosen at random (if set to -1) or the value selected by the user. The first image is generated using the variation seed, the next with the variation seed + 1, and so on.
|
313 |
+
|
314 |
+
### With Dynamic Prompts Enabled in Random/Standard Mode
|
315 |
+
1. Seed set to -1: The situation is the same as the first item above, but the prompt is chosen using the same seed (if using the random prompt generator).
|
316 |
+
2. Seed set to a number > -1: The situation is the same as the second item above, except that a random prompt is generated using the given seed (if using the prompt generator).
|
317 |
+
3. Fixed seed checkbox checked: Instead of incrementing the seed, the same seed is used for all images and prompts, i.e., you generate the same image (not very useful).
|
318 |
+
4. Fixed seed and unlink seed from prompt checkboxes checked: A random seed is used for the prompt, and the same seed is used for images. This is useful if you want to test how different prompts affect the same image.
|
319 |
+
|
320 |
+
### Variation Seeds with Dynamic Prompts
|
321 |
+
1. Variation strength set to 0: Variations are ignored.
|
322 |
+
2. Variation set to a number > 0: A variation seed is assigned to every image, incrementing by one each time. However, only 1 prompt is generated since you are looking for variations of the same image.
|
323 |
+
|
324 |
+
### Combinatorial Mode with Variation Strength > 0
|
325 |
+
In this case, it only generates the first image for you, which is probably not what you want. To get the desired results, you might need to adjust the settings or use a different mode.
|
ex/dynamic-prompts/_tools/import_noodle_soup_prompts.py
ADDED
@@ -0,0 +1,87 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""
|
2 |
+
Import collections/nsp from https://github.com/WASasquatch/noodle-soup-prompts.
|
3 |
+
|
4 |
+
This script is intended to be run from the root of the repository;
|
5 |
+
it's best to delete the existing collections/nsp folder first to avoid
|
6 |
+
duplicate entries.
|
7 |
+
|
8 |
+
You would then import these via the WebUI to your wildcards collection.
|
9 |
+
"""
|
10 |
+
import collections
|
11 |
+
import logging
|
12 |
+
from pathlib import Path
|
13 |
+
|
14 |
+
import requests
|
15 |
+
|
16 |
+
logger = logging.getLogger(__name__)
|
17 |
+
|
18 |
+
|
19 |
+
def get_tag_group(tag):
|
20 |
+
return tag.partition("-")[0]
|
21 |
+
|
22 |
+
|
23 |
+
def get_grouped_tags():
|
24 |
+
pantry_url = "https://raw.githubusercontent.com/WASasquatch/noodle-soup-prompts/main/nsp_pantry.json"
|
25 |
+
resp = requests.get(pantry_url)
|
26 |
+
resp.raise_for_status()
|
27 |
+
pantry = {tag.lower(): entries for (tag, entries) in resp.json().items()}
|
28 |
+
grouped_tags = collections.defaultdict(list)
|
29 |
+
for tag, entries in pantry.items():
|
30 |
+
grouped_tags[get_tag_group(tag)].append((tag, entries))
|
31 |
+
return grouped_tags
|
32 |
+
|
33 |
+
|
34 |
+
def main():
|
35 |
+
count_files = 0
|
36 |
+
current_path = Path.cwd()
|
37 |
+
if current_path.name == "_tools":
|
38 |
+
current_path = current_path.parent
|
39 |
+
|
40 |
+
can_overwrite = None
|
41 |
+
|
42 |
+
grouped_tags = get_grouped_tags()
|
43 |
+
collections_dir = current_path / "collections"
|
44 |
+
|
45 |
+
if not collections_dir.exists():
|
46 |
+
print(
|
47 |
+
"Could not find the collections directory. You should run this from the root of the repository",
|
48 |
+
)
|
49 |
+
else:
|
50 |
+
for tag_group_name, tags_in_group in sorted(grouped_tags.items()):
|
51 |
+
tag_group_name = (
|
52 |
+
"nsp" if len(tags_in_group) == 1 else f"nsp-{tag_group_name}"
|
53 |
+
)
|
54 |
+
for tag, entries in sorted(tags_in_group):
|
55 |
+
filename = collections_dir / f"./nsp/{tag_group_name}/{tag}.txt"
|
56 |
+
filename.parent.mkdir(parents=True, exist_ok=True)
|
57 |
+
|
58 |
+
if can_overwrite is None and filename.exists():
|
59 |
+
answer = input(
|
60 |
+
f"Skipping {filename} as it already exists. Should we overwrite existing files? (y/n)",
|
61 |
+
)
|
62 |
+
if answer.strip().lower() == "y":
|
63 |
+
can_overwrite = True
|
64 |
+
else:
|
65 |
+
can_overwrite = False
|
66 |
+
|
67 |
+
if can_overwrite is None or can_overwrite is True:
|
68 |
+
count_files += 1
|
69 |
+
with filename.open("w", encoding="utf-8") as f:
|
70 |
+
for entry in sorted(entries):
|
71 |
+
try:
|
72 |
+
f.write(f"{entry}\n")
|
73 |
+
except UnicodeEncodeError:
|
74 |
+
logger.warning(f"Error writing {entry} to {filename}")
|
75 |
+
|
76 |
+
print(f"{filename}: {len(entries)} entries")
|
77 |
+
|
78 |
+
print("")
|
79 |
+
print(f"{count_files} files copied to {collections_dir}")
|
80 |
+
if count_files > 0:
|
81 |
+
print(
|
82 |
+
"You should now import these via the WebUI to your wildcards collection using the Wildcards Manager tab.",
|
83 |
+
)
|
84 |
+
|
85 |
+
|
86 |
+
if __name__ == "__main__":
|
87 |
+
main()
|
ex/dynamic-prompts/collections/artists/European Art/baroque/baroque.txt
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
__artists/European Art/baroque/italian_baroque_painters__
|
2 |
+
__artists/European Art/baroque/french_baroque_painters__
|
3 |
+
__artists/European Art/baroque/british_baroque_painters__
|
4 |
+
__artists/European Art/baroque/czech_baroque_painters__
|
5 |
+
__artists/European Art/baroque/danish_baroque_painters__
|
6 |
+
__artists/European Art/baroque/german_baroque_painters__
|
7 |
+
__artists/European Art/baroque/greek_baroque_painters__
|
8 |
+
__artists/European Art/baroque/netherlandish_baroque_painters__
|
9 |
+
__artists/European Art/baroque/flemish_baroque_painters__
|
10 |
+
__artists/European Art/baroque/quadratura__
|
11 |
+
__artists/European Art/baroque/spanish_baroque_painters__
|
ex/dynamic-prompts/collections/artists/European Art/baroque/bentvueghels.txt
ADDED
@@ -0,0 +1,114 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Abraham Brueghel
|
2 |
+
Abraham Genoels
|
3 |
+
Adriaen Foly
|
4 |
+
Adriaen Honich
|
5 |
+
Adriaen van der Cabel
|
6 |
+
Albertus Clouwet
|
7 |
+
Albert van Spiers
|
8 |
+
Andries Both
|
9 |
+
Anthoni Schoonjans
|
10 |
+
Augustinus Terwesten
|
11 |
+
Bartholomeus Appelman
|
12 |
+
Bartholomeus Breenbergh
|
13 |
+
Bernard de Bailliu
|
14 |
+
Bonaventura van Overbeek
|
15 |
+
Carel de Vogelaer
|
16 |
+
Caspar van Wittel
|
17 |
+
Christian Reder
|
18 |
+
Cornelis Bloemaert
|
19 |
+
Cornelis de Bruijn
|
20 |
+
Cornelis Schut
|
21 |
+
Cornelis van Poelenburgh
|
22 |
+
Cornelis van Rijssen
|
23 |
+
Cornelis van Slingeland
|
24 |
+
Daniel Mijtens the Younger
|
25 |
+
Daniel Seiter
|
26 |
+
David Beck
|
27 |
+
David de Coninck
|
28 |
+
Dirck van Baburen
|
29 |
+
Domenicus van Wijnen
|
30 |
+
Ezaias Terwesten
|
31 |
+
Franciscus de Neve (II)
|
32 |
+
Francis van Bossuit
|
33 |
+
Francoys Dancx
|
34 |
+
Frans Beeldemaker
|
35 |
+
Franz Ludwig Raufft
|
36 |
+
Franz Werner von Tamm
|
37 |
+
Gaspar de Witte
|
38 |
+
Gerard van Kuijl
|
39 |
+
Hans IV Jordaens
|
40 |
+
Hendrick Mommers
|
41 |
+
Hendrik Frans van Lint
|
42 |
+
Herman van Swanevelt
|
43 |
+
Hubertus Quellinus
|
44 |
+
Ignatius Croon
|
45 |
+
Isaac de Moucheron
|
46 |
+
Jacob de Decker
|
47 |
+
Jacob de Heusch
|
48 |
+
Jacob Ferdinand Voet
|
49 |
+
Jacob Leyssens
|
50 |
+
Jacob Toorenvliet
|
51 |
+
Jacobus de Baen
|
52 |
+
Jacob van der Does
|
53 |
+
Jacob van Staverden
|
54 |
+
Jacques Blondeau
|
55 |
+
Jacques Vaillant (painter)
|
56 |
+
Jan Asselijn
|
57 |
+
Jan Baptist Brueghel
|
58 |
+
Jan Baptist Weenix
|
59 |
+
Jan Boeckhorst
|
60 |
+
Jan Dirksz Both
|
61 |
+
Jan Erasmus Quellinus
|
62 |
+
Jan Frans van Bloemen
|
63 |
+
Jan Fyt
|
64 |
+
Jan Linsen
|
65 |
+
Jan Theunisz Blanckerhoff
|
66 |
+
Jan van Bijlert
|
67 |
+
Jan van Bunnik
|
68 |
+
Jean Baptiste Assenede
|
69 |
+
Jean Ducamps
|
70 |
+
Joachim von Sandrart
|
71 |
+
Johannes Glauber
|
72 |
+
Johannes Gottlieb Glauber
|
73 |
+
Johannes Jansz. van Bronckhorst
|
74 |
+
Johann Liss
|
75 |
+
Johann Wilhelm Baur
|
76 |
+
Johan Teyler
|
77 |
+
Johan Zierneels
|
78 |
+
Karel Dujardin
|
79 |
+
Karel Škréta
|
80 |
+
Leonaert Bramer
|
81 |
+
Luigi Primo
|
82 |
+
Mattheus Terwesten
|
83 |
+
Matthias Withoos
|
84 |
+
Nicolaas Piemont
|
85 |
+
Nicolaes Latombe
|
86 |
+
Norbert van Bloemen
|
87 |
+
Otto Marseus van Schrieck
|
88 |
+
Paulus Bor
|
89 |
+
Philipp Peter Roos
|
90 |
+
Philips de Momper the Elder
|
91 |
+
Pieter Anthonisz. van Groenewegen
|
92 |
+
Pieter de Zeelander
|
93 |
+
Pieter Fris
|
94 |
+
Pieter Hofman
|
95 |
+
Pieter Mulier II
|
96 |
+
Pieter van Bloemen
|
97 |
+
Pieter van der Hulst (IV)
|
98 |
+
Pieter van Laer
|
99 |
+
Pieter Verbrugghen the Younger
|
100 |
+
Reinier van Persijn
|
101 |
+
Robbert Duval (1639–1732)
|
102 |
+
Samuel Dirksz van Hoogstraten
|
103 |
+
Simon Ardé
|
104 |
+
Theodoor Wilkens
|
105 |
+
Theodor van der Schuer
|
106 |
+
Thomas Mathisen
|
107 |
+
Tyman Arentsz. Cracht
|
108 |
+
Willem Doudijns
|
109 |
+
Willem Gabron
|
110 |
+
Willem van Aelst
|
111 |
+
Willem van Bemmel
|
112 |
+
Willem van Ingen
|
113 |
+
Wouter Crabeth II
|
114 |
+
Wybrand de Geest
|
ex/dynamic-prompts/collections/artists/European Art/baroque/british_baroque_painters.txt
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Alexander Cooper
|
2 |
+
Cornelius Johnson
|
3 |
+
Godfrey Kneller
|
4 |
+
Jan Griffier
|
5 |
+
Joan Carlile
|
6 |
+
John Hayls
|
7 |
+
Mary Beale
|
8 |
+
Richard Gibson
|
ex/dynamic-prompts/collections/artists/European Art/baroque/czech_baroque_painters.txt
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Petr Brandl
|
2 |
+
Jan Kryštof Liška
|
3 |
+
Wenzel Lorenz Reiner
|
4 |
+
Karel Škréta
|
5 |
+
Anton Stevens
|
ex/dynamic-prompts/collections/artists/European Art/baroque/danish_baroque_painters.txt
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Adriaen Foly
|
2 |
+
Andreas Brünniche
|
3 |
+
Andreas Møller
|
4 |
+
Benoît Le Coffre
|
5 |
+
Bernhard Keil
|
6 |
+
Ebbe Ulfeldt
|
7 |
+
Heinrich Jansen
|
8 |
+
Jacques d'Agar
|
9 |
+
Johan Jacob Bruun
|
10 |
+
Jürgen Ovens
|
11 |
+
Lambert van Haven
|
12 |
+
Pieter Isaacsz
|
ex/dynamic-prompts/collections/artists/European Art/baroque/dutch_goldenage_painters.txt
ADDED
@@ -0,0 +1,828 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Aart Jansz Druyvesteyn
|
2 |
+
Abraham Beerstraaten
|
3 |
+
Abraham Begeyn
|
4 |
+
Abraham Bloemaert
|
5 |
+
Abraham Bosschaert
|
6 |
+
Abraham Casembroot
|
7 |
+
Abraham de Heusch
|
8 |
+
Abraham de Verwer
|
9 |
+
Abraham de Vries
|
10 |
+
Abraham Diepraam
|
11 |
+
Abraham Furnerius
|
12 |
+
Abraham Hondius
|
13 |
+
Abraham Lambertsz van den Tempel
|
14 |
+
Abraham Mignon
|
15 |
+
Abraham Staphorst
|
16 |
+
Abraham Storck
|
17 |
+
Abraham Susenier
|
18 |
+
Abraham van Beijeren
|
19 |
+
Abraham van Calraet
|
20 |
+
Abraham van Cuylenborch
|
21 |
+
Abraham van den Hecken
|
22 |
+
Abraham van der Haagen
|
23 |
+
Abraham van der Hoef
|
24 |
+
Abraham van Diepenbeeck
|
25 |
+
Abraham van Dijck
|
26 |
+
Abraham Willaerts
|
27 |
+
Abraham Wuchters
|
28 |
+
Adam Colonia
|
29 |
+
Adam de Colone
|
30 |
+
Adam Pynacker
|
31 |
+
Adam van Breen
|
32 |
+
Adam Willaerts
|
33 |
+
Adriaan Bloemaert
|
34 |
+
Adriaan Gerritsz de Vrije
|
35 |
+
Adriaen Backer
|
36 |
+
Adriaen Coorte
|
37 |
+
Adriaen Cornelisz Beeldemaker
|
38 |
+
Adriaen Cornelisz van Linschoten
|
39 |
+
Adriaen Hanneman
|
40 |
+
Adriaen Hendriksz Verboom
|
41 |
+
Adriaen Honich
|
42 |
+
Adriaen Jansz Kraen
|
43 |
+
Adriaen Oudendijck
|
44 |
+
Adriaen van der Burch
|
45 |
+
Adriaen van der Cabel
|
46 |
+
Adriaen van der Spelt
|
47 |
+
Adriaen van der Werff
|
48 |
+
Adriaen van de Velde
|
49 |
+
Adriaen van de Venne
|
50 |
+
Adriaen van Eemont
|
51 |
+
Adriaen van Gaesbeeck
|
52 |
+
Adriaen van Nieulandt
|
53 |
+
Adriaen van Ostade
|
54 |
+
Adriaen Verdoel
|
55 |
+
Adriana Spilberg
|
56 |
+
Aelbert Cuyp
|
57 |
+
Aert Anthoniszoon
|
58 |
+
Aert de Gelder
|
59 |
+
Aert Jansz Marienhof
|
60 |
+
Aert Pietersz
|
61 |
+
Aert van der Neer
|
62 |
+
Aert van Waes
|
63 |
+
Albert Eckhout
|
64 |
+
Albert Jansz. Klomp
|
65 |
+
Albert Meijeringh
|
66 |
+
Albert van Spiers
|
67 |
+
Aleijda Wolfsen
|
68 |
+
Alexander Westerhout
|
69 |
+
Alida Withoos
|
70 |
+
Allaert van Everdingen
|
71 |
+
Ambrosius Bosschaert
|
72 |
+
Ambrosius Bosschaert II
|
73 |
+
Andries Beeckman
|
74 |
+
Andries Both
|
75 |
+
Andries Vaillant
|
76 |
+
Anna Cornelia Holt
|
77 |
+
Anna Maria van Schurman
|
78 |
+
Anna Ruysch
|
79 |
+
Anthonie Beerstraaten
|
80 |
+
Anthonie de Lorme
|
81 |
+
Anthonie Hals
|
82 |
+
Anthonie Jansz. van der Croos
|
83 |
+
Anthonie Leemans
|
84 |
+
Anthonie Palamedesz.
|
85 |
+
Anthonie van Borssom
|
86 |
+
Anthonie Verstraelen
|
87 |
+
Anthony Vreem
|
88 |
+
Antonie Waterloo
|
89 |
+
Arent Arentsz
|
90 |
+
Arnold Houbraken
|
91 |
+
Arnoldus van Anthonissen
|
92 |
+
Arnold van Ravesteyn
|
93 |
+
Arnout Elsevier
|
94 |
+
Ary de Vois
|
95 |
+
Ary Huybertsz Verveer
|
96 |
+
Balthasar van der Ast
|
97 |
+
Balthasar van der Veen
|
98 |
+
Balthazar Gerbier
|
99 |
+
Bamboccianti
|
100 |
+
Barend Bispinck
|
101 |
+
Barend Graat
|
102 |
+
Barend van der Meer
|
103 |
+
Barend van Eijsen
|
104 |
+
Barend van Someren
|
105 |
+
Barent Avercamp
|
106 |
+
Barent Fabritius
|
107 |
+
Barent Gael
|
108 |
+
Barent van Kalraet
|
109 |
+
Bartholomeus Appelman
|
110 |
+
Bartholomeus Assteyn
|
111 |
+
Bartholomeus Breenbergh
|
112 |
+
Bartholomeus Maton
|
113 |
+
Bartholomeus Meyburgh
|
114 |
+
Bartholomeus Molenaer
|
115 |
+
Bartholomeus van Bassen
|
116 |
+
Bartholomeus van der Helst
|
117 |
+
Bartram de Fouchier
|
118 |
+
Bastiaan Govertsz van der Leeuw
|
119 |
+
Benjamin Gerritsz Cuyp
|
120 |
+
Bentvueghels
|
121 |
+
Bernardus van Schijndel
|
122 |
+
Bernard Vaillant
|
123 |
+
Caesar van Everdingen
|
124 |
+
Carel de Moor
|
125 |
+
Carel Fabritius
|
126 |
+
Carel van Savoyen
|
127 |
+
Caspar Netscher
|
128 |
+
Caspar van Wittel
|
129 |
+
Catharina Oostfries
|
130 |
+
Catharina van Knibbergen
|
131 |
+
Charles Cornelisz. de Hooch
|
132 |
+
Christiaan Coevershoff
|
133 |
+
Christiaen Jansz van Bieselingen
|
134 |
+
Christiaen Striep
|
135 |
+
Christiaen van Couwenbergh
|
136 |
+
Christoffel Pierson
|
137 |
+
Christoffel Puytlinck
|
138 |
+
Christoffel van den Berghe
|
139 |
+
Claes Corneliszoon Moeyaert
|
140 |
+
Claes Dirksz van der Heck
|
141 |
+
Claes Isaacsz. van Swanenburg
|
142 |
+
Claes Jacobsz van der Heck
|
143 |
+
Claes Pietersz van der Meulen
|
144 |
+
Claes van Beresteyn
|
145 |
+
Claes van Heussen
|
146 |
+
Clara Peeters
|
147 |
+
Claude de Jongh
|
148 |
+
Confrerie Pictura
|
149 |
+
Constantijn à Renesse
|
150 |
+
Cornelia van Marle
|
151 |
+
Cornelis Beelt
|
152 |
+
Cornelis Biltius
|
153 |
+
Cornelis Bisschop
|
154 |
+
Cornelis Bloemaert
|
155 |
+
Cornelis Brisé
|
156 |
+
Cornelis Brouwer
|
157 |
+
Cornelis Claesz van Wieringen
|
158 |
+
Cornelis de Bie
|
159 |
+
Cornelis de Heem
|
160 |
+
Cornelis de Man
|
161 |
+
Cornelis Droochsloot
|
162 |
+
Cornelis Dusart
|
163 |
+
Cornelis Engelsz
|
164 |
+
Cornelis Gerritsz Decker
|
165 |
+
Cornelis Holsteyn
|
166 |
+
Cornelis IJsbrantsz Cussens
|
167 |
+
Cornelis Jacobsz Delff
|
168 |
+
Cornelis Ketel
|
169 |
+
Cornelis Kick
|
170 |
+
Cornelis Kruys
|
171 |
+
Cornelis Liefrinck
|
172 |
+
Cornelis Pietersz Bega
|
173 |
+
Cornelis Saftleven
|
174 |
+
Cornelis Snellinck
|
175 |
+
Cornelis Stooter
|
176 |
+
Cornelis Symonsz van der Schalcke
|
177 |
+
Cornelis van der Meulen
|
178 |
+
Cornelis van der Voort
|
179 |
+
Cornelis van Haarlem
|
180 |
+
Cornelis van Poelenburgh
|
181 |
+
Cornelis van Slingeland
|
182 |
+
Cornelis Verbeeck
|
183 |
+
Cornelis Vroom
|
184 |
+
Cornelius Janson van Ceulen the Younger
|
185 |
+
Cornelius Johnson
|
186 |
+
Crijn Hendricksz Volmarijn
|
187 |
+
Daniël de Blieck
|
188 |
+
Daniël Mijtens
|
189 |
+
Daniel Mijtens the Younger
|
190 |
+
Daniël Schellinks
|
191 |
+
Daniel Thivart
|
192 |
+
Daniël Tomberg
|
193 |
+
Daniel Vertangen
|
194 |
+
Daniel Vosmaer
|
195 |
+
David Bailly
|
196 |
+
David Beck
|
197 |
+
David Colijns
|
198 |
+
David Cornelisz de Heem
|
199 |
+
David Davidsz de Heem
|
200 |
+
David de Haen
|
201 |
+
David de Meyne
|
202 |
+
David van der Plas
|
203 |
+
David Vinckboons
|
204 |
+
Diana Glauber
|
205 |
+
Dionys Verburg
|
206 |
+
Dirck Bleker
|
207 |
+
Dirck Cornelis de Hooch
|
208 |
+
Dirck Dalens the Elder
|
209 |
+
Dirck de Bray
|
210 |
+
Dirck de Quade van Ravesteyn
|
211 |
+
Dirck Ferreris
|
212 |
+
Dirck Govertsz
|
213 |
+
Dirck Hals
|
214 |
+
Dirck Helmbreker
|
215 |
+
Dirck van Baburen
|
216 |
+
Dirck van Bergen
|
217 |
+
Dirck van Delen
|
218 |
+
Dirck van der Lisse
|
219 |
+
Dirck van Santvoort
|
220 |
+
Dirck Wijntrack
|
221 |
+
Dirk Dalens
|
222 |
+
Dirk de Vrije
|
223 |
+
Dirk Maas
|
224 |
+
Dirk Meerkerk
|
225 |
+
Dirk Pietersz
|
226 |
+
Dirk Rafaelsz Camphuysen
|
227 |
+
Dirk Stoop
|
228 |
+
Dirk Valkenburg
|
229 |
+
Dirk van Hoogstraten
|
230 |
+
Domenicus van Wijnen
|
231 |
+
Dominicus van Tol
|
232 |
+
Douwe Juwes de Dowe
|
233 |
+
Dutch Golden Age painting
|
234 |
+
Egbert van der Poel
|
235 |
+
Egbert van Heemskerck
|
236 |
+
Eglon van der Neer
|
237 |
+
Elias van den Broeck
|
238 |
+
Elias Vonck
|
239 |
+
Emanuel de Witte
|
240 |
+
Emanuel Murant
|
241 |
+
Esaias Boursse
|
242 |
+
Esaias van de Velde
|
243 |
+
Eva van Marle
|
244 |
+
Everard Crijnsz. van der Maes
|
245 |
+
Evert Collier
|
246 |
+
Evert Oudendijck
|
247 |
+
Evert van Aelst
|
248 |
+
Ferdinand Bol
|
249 |
+
Fijnschilder
|
250 |
+
Floris van Dyck
|
251 |
+
Floris van Schooten
|
252 |
+
Franciscus Carree
|
253 |
+
François van Knibbergen
|
254 |
+
François Verwilt
|
255 |
+
Francoys Dancx
|
256 |
+
Frans Beeldemaker
|
257 |
+
Frans de Hulst
|
258 |
+
Frans Hals
|
259 |
+
Frans Hals the Younger
|
260 |
+
Frans Menton
|
261 |
+
Frans Pietersz de Grebber
|
262 |
+
Frans Post
|
263 |
+
Frans van Mieris the Elder
|
264 |
+
Frans Withoos
|
265 |
+
Frederik de Moucheron
|
266 |
+
Gabriël Metsu
|
267 |
+
Geertgen Wyntges
|
268 |
+
Geertruydt Roghman
|
269 |
+
Gerard de Lairesse
|
270 |
+
Gerard Donck
|
271 |
+
Gerard Edema
|
272 |
+
Gerard Hoet
|
273 |
+
Gerard Houckgeest
|
274 |
+
Gerard Pietersz van Zijl
|
275 |
+
Gerard Soest
|
276 |
+
Gerard ter Borch
|
277 |
+
Gerard ter Borch the Elder
|
278 |
+
Gerard van Deynen
|
279 |
+
Gerard van Honthorst
|
280 |
+
Gerard van Kuijl
|
281 |
+
Gerbrand van den Eeckhout
|
282 |
+
Gerret Willemsz. Heda
|
283 |
+
Gerrit Battem
|
284 |
+
Gerrit Berckheyde
|
285 |
+
Gerrit Claesz Bleker
|
286 |
+
Gerrit de Hooch
|
287 |
+
Gerrit de Wet
|
288 |
+
Gerrit Dou
|
289 |
+
Gerrit Gerritsz Cuyp
|
290 |
+
Gerrit Lundens
|
291 |
+
Gerrit Pietersz Sweelink
|
292 |
+
Gerrit van Santen
|
293 |
+
Gerrit van Uylenburgh
|
294 |
+
Gerrit Willemsz Horst
|
295 |
+
Gesina ter Borch
|
296 |
+
Gijsbert d'Hondecoeter
|
297 |
+
Gijsbert Verhoek
|
298 |
+
Gillis d'Hondecoeter
|
299 |
+
Gillis Gillisz. de Bergh
|
300 |
+
Gillis Rombouts
|
301 |
+
Gillis Schagen
|
302 |
+
Godfried Schalcken
|
303 |
+
Govert Dircksz Camphuysen
|
304 |
+
Govert Flinck
|
305 |
+
Govert van der Leeuw
|
306 |
+
Guillam Dubois
|
307 |
+
Guilliam du Gardijn
|
308 |
+
Hans de Jode
|
309 |
+
Hans Gillisz. Bollongier
|
310 |
+
Hans Goderis
|
311 |
+
Hans IV Jordaens
|
312 |
+
Harmen Hals
|
313 |
+
Harmen Steenwijck
|
314 |
+
Heerman Witmont
|
315 |
+
Heiman Dullaert
|
316 |
+
Hendrick Avercamp
|
317 |
+
Hendrick Berckman
|
318 |
+
Hendrick Bloemaert
|
319 |
+
Hendrick Bogaert
|
320 |
+
Hendrick Cornelisz. van Vliet
|
321 |
+
Hendrick Cornelisz Vroom
|
322 |
+
Hendrick Couturier
|
323 |
+
Hendrick Danckerts
|
324 |
+
Hendrick de Meijer
|
325 |
+
Hendrick Dubbels
|
326 |
+
Hendrick Fromantiou
|
327 |
+
Hendrick Goltzius
|
328 |
+
Hendrick Goudt
|
329 |
+
Hendrick Mommers
|
330 |
+
Hendrick ten Oever
|
331 |
+
Hendrick ter Brugghen
|
332 |
+
Hendrick van Anthonissen
|
333 |
+
Hendrick van der Burgh
|
334 |
+
Hendrick van Someren
|
335 |
+
Hendrick van Streeck
|
336 |
+
Hendrik Carré
|
337 |
+
Hendrik Gerritsz Pot
|
338 |
+
Hendrik Graauw
|
339 |
+
Hendrik Heerschop
|
340 |
+
Hendrik Martenszoon Sorgh
|
341 |
+
Hendrik Rietschoof
|
342 |
+
Hendrik Schoock
|
343 |
+
Hendrik van Minderhout
|
344 |
+
Hendrik van Steenwijk II
|
345 |
+
Hendrik Verschuring
|
346 |
+
Henry Ferguson
|
347 |
+
Hercules Seghers
|
348 |
+
Herman Doncker
|
349 |
+
Herman Naiwincx
|
350 |
+
Herman Saftleven
|
351 |
+
Herman van Aldewereld
|
352 |
+
Herman van der Mast
|
353 |
+
Herman van Swanevelt
|
354 |
+
Herman Verelst
|
355 |
+
Horatius Paulijn
|
356 |
+
Hubert van Ravesteyn
|
357 |
+
Huchtenburg
|
358 |
+
Huijgh Pietersz. Voskuijl
|
359 |
+
Huybrecht Jacobsz Grimani
|
360 |
+
Isaac Claesz. van Swanenburg
|
361 |
+
Isaac Colonia
|
362 |
+
Isaac de Jouderville
|
363 |
+
Isaac Ducart
|
364 |
+
Isaac Elias
|
365 |
+
Isaack Gilsemans
|
366 |
+
Isaack Luttichuys
|
367 |
+
Isaac Koedijck
|
368 |
+
Isaac Koene
|
369 |
+
Isaack van Ruisdael
|
370 |
+
Isaac Paling
|
371 |
+
Isaac Sailmaker
|
372 |
+
Isaac van Duynen
|
373 |
+
Isaac van Ostade
|
374 |
+
Isaak van Nickelen
|
375 |
+
Isac Vromans
|
376 |
+
Israel Covyn
|
377 |
+
Jacob Adriaensz Backer
|
378 |
+
Jacob Adriaensz Bellevois
|
379 |
+
Jacob Biltius
|
380 |
+
Jacob Block
|
381 |
+
Jacob de Decker
|
382 |
+
Jacob de Gheyn II
|
383 |
+
Jacob de Gheyn III
|
384 |
+
Jacob de Heusch
|
385 |
+
Jacob de Wet II
|
386 |
+
Jacob de Wolf
|
387 |
+
Jacob Duck
|
388 |
+
Jacob Esselens
|
389 |
+
Jacob Gerritsz. Cuyp
|
390 |
+
Jacob Gerritsz. Loef
|
391 |
+
Jacob Gillig
|
392 |
+
Jacob Isaacsz. van Swanenburg
|
393 |
+
Jacob Jansz. Coeman
|
394 |
+
Jacob Jansz van Velsen
|
395 |
+
Jacob Knijff
|
396 |
+
Jacob Koninck
|
397 |
+
Jacob Lambrechtsz. Loncke
|
398 |
+
Jacob Levecq
|
399 |
+
Jacob Marrel
|
400 |
+
Jacob Moelaert
|
401 |
+
Jacob Ochtervelt
|
402 |
+
Jacob Potma
|
403 |
+
Jacob Pynas
|
404 |
+
Jacob Rotius
|
405 |
+
Jacob Salomonsz van Ruysdael
|
406 |
+
Jacob Toorenvliet
|
407 |
+
Jacobus de Baen
|
408 |
+
Jacobus Mancadan
|
409 |
+
Jacobus Storck
|
410 |
+
Jacob van Bunnik
|
411 |
+
Jacob van Campen
|
412 |
+
Jacob van der Does
|
413 |
+
Jacob van der Roer van Dordrecht
|
414 |
+
Jacob van der Sluys
|
415 |
+
Jacob van der Ulft
|
416 |
+
Jacob van Geel
|
417 |
+
Jacob van Loo
|
418 |
+
Jacob van Moscher
|
419 |
+
Jacob van Musscher
|
420 |
+
Jacob van Ruisdael
|
421 |
+
Jacob van Staverden
|
422 |
+
Jacob van Walscapelle
|
423 |
+
Jacob Vosmaer
|
424 |
+
Jacob Vrel
|
425 |
+
Jacob Willemsz Delff the Younger
|
426 |
+
Jacob Willemszoon de Wet
|
427 |
+
Jacques de Claeuw
|
428 |
+
Jacques Vaillant
|
429 |
+
Jacques Waben
|
430 |
+
Jan Abrahamsz Beerstraaten
|
431 |
+
Jan Adriaensz van Staveren
|
432 |
+
Jan Aelbertsz Riethoorn
|
433 |
+
Jan Albertsz Rotius
|
434 |
+
Jan Ariens Duif
|
435 |
+
Jan Asselijn
|
436 |
+
Jan Baptist van Fornenburgh
|
437 |
+
Jan Baptist Weenix
|
438 |
+
Jan Claesz
|
439 |
+
Jan Claesz Rietschoof
|
440 |
+
Jan Coelenbier
|
441 |
+
Jan Daemen Cool
|
442 |
+
Jan Damesz de Veth
|
443 |
+
Jan Davidsz. de Heem
|
444 |
+
Jan de Baen
|
445 |
+
Jan de Bisschop
|
446 |
+
Jan de Bray
|
447 |
+
Jan de Groot
|
448 |
+
Jan den Uyl
|
449 |
+
Jan de Visscher
|
450 |
+
Jan Dirksz Both
|
451 |
+
Jan Franse Verzijl
|
452 |
+
Jan Frans van Douven
|
453 |
+
Jan Gabrielsz Sonjé
|
454 |
+
Jan Gerritsz van Bronckhorst
|
455 |
+
Jan Gillisz van Vliet
|
456 |
+
Jan Goedart
|
457 |
+
Jan Griffier
|
458 |
+
Jan Hackaert
|
459 |
+
Jan Hals
|
460 |
+
Jan Harmensz. Muller
|
461 |
+
Jan Hoogsaat
|
462 |
+
Jan Jansz Buesem
|
463 |
+
Jan Jansz. de Stomme
|
464 |
+
Jan Janszoon de Heem
|
465 |
+
Jan Jansz. Treck
|
466 |
+
Jan Jansz van de Velde
|
467 |
+
Jan Janz Slop
|
468 |
+
Jan Karel Donatus van Beecq
|
469 |
+
Jan Lagoor
|
470 |
+
Jan Lievens
|
471 |
+
Jan Linsen
|
472 |
+
Jan Looten
|
473 |
+
Jan Maertz Engelsman
|
474 |
+
Jan Martszen de Jonge
|
475 |
+
Jan Matham
|
476 |
+
Jan Meerhout
|
477 |
+
Jan Micker
|
478 |
+
Jan Miense Molenaer
|
479 |
+
Jan Moninckx
|
480 |
+
Jan Olis
|
481 |
+
Jan Philipsz van Bouckhorst
|
482 |
+
Jan Porcellis
|
483 |
+
Jan Pynas
|
484 |
+
Jan Savery
|
485 |
+
Jan Snellinck
|
486 |
+
Jan Soukens
|
487 |
+
Jan Steen
|
488 |
+
Jan Tengnagel
|
489 |
+
Jan Theunisz Blanckerhoff
|
490 |
+
Jan Vaillant
|
491 |
+
Jan van Aken
|
492 |
+
Jan van Assen
|
493 |
+
Jan van Bijlert
|
494 |
+
Jan van Bunnik
|
495 |
+
Jan van Call
|
496 |
+
Jan van de Cappelle
|
497 |
+
Jan van den Bergh
|
498 |
+
Jan van der Heyden
|
499 |
+
Jan van der Lijs
|
500 |
+
Jan van de Velde
|
501 |
+
Jan van Goyen
|
502 |
+
Jan van Hoogstraten
|
503 |
+
Jan van Kessel
|
504 |
+
Jan van Leyden
|
505 |
+
Jan van Mieris
|
506 |
+
Jan van Neck
|
507 |
+
Jan van Nickelen
|
508 |
+
Jan van Noordt
|
509 |
+
Jan van Oolen
|
510 |
+
Jan van Ossenbeeck
|
511 |
+
Jan van Pee
|
512 |
+
Jan van Ravesteyn
|
513 |
+
Jan Verkolje
|
514 |
+
Jan Vermeer van Haarlem
|
515 |
+
Jan Vermeer van Haarlem the Elder
|
516 |
+
Jan Vermeer van Utrecht
|
517 |
+
Jan Victors
|
518 |
+
Jan Vonck
|
519 |
+
Jan Weenix
|
520 |
+
Jan Wijnants
|
521 |
+
Jan Willemsz Lapp
|
522 |
+
Jan Willemsz. van der Wilde
|
523 |
+
Jan Wils
|
524 |
+
Jan Worst
|
525 |
+
Jan Woutersz Stap
|
526 |
+
Jan Wouwerman
|
527 |
+
Jan Wyck
|
528 |
+
Jasper van den Bos
|
529 |
+
Jelle Reyners
|
530 |
+
Jeronimus Sweerts
|
531 |
+
Jeronymus van Diest
|
532 |
+
Joachim Govertsz Camphuysen
|
533 |
+
Joachim von Sandrart
|
534 |
+
Joachim Wtewael
|
535 |
+
Joanna Koerten
|
536 |
+
Joan van der Spriet
|
537 |
+
Job Adriaenszoon Berckheyde
|
538 |
+
Johan Bara
|
539 |
+
Johan Danckerts
|
540 |
+
Johan le Ducq
|
541 |
+
Johannes Borman
|
542 |
+
Johannes Bosschaert
|
543 |
+
Johannes Buns
|
544 |
+
Johannes Colaert
|
545 |
+
Johannes Cornelisz Verspronck
|
546 |
+
Johannes Fabritius
|
547 |
+
Johannes Glauber
|
548 |
+
Johannes Gottlieb Glauber
|
549 |
+
Johannes Jansz. van Bronckhorst
|
550 |
+
Johannes Leemans
|
551 |
+
Johannes Lingelbach
|
552 |
+
Johannes Moreelse
|
553 |
+
Johannes Mytens
|
554 |
+
Johannes Spilberg
|
555 |
+
Johannes Thopas
|
556 |
+
Johannes van Bronckhorst
|
557 |
+
Johannes van der Aeck
|
558 |
+
Johannes van der Beeck
|
559 |
+
Johannes van der Bent
|
560 |
+
Johannes van Haensbergen
|
561 |
+
Johannes van Wijckersloot
|
562 |
+
Johannes Vermeer
|
563 |
+
Johannes Vingboons
|
564 |
+
Johannes Vollevens
|
565 |
+
Johannes Withoos
|
566 |
+
Johan Starrenberg
|
567 |
+
Johan Teyler
|
568 |
+
Johan van Nes
|
569 |
+
Johan Zierneels
|
570 |
+
John Verelst
|
571 |
+
Joost Cornelisz Droochsloot
|
572 |
+
Joost van Geel
|
573 |
+
Joris van der Haagen
|
574 |
+
Joris van Schooten
|
575 |
+
Joseph de Bray
|
576 |
+
Josua de Grave
|
577 |
+
Jozef Oostfries
|
578 |
+
Judith Leyster
|
579 |
+
Julius Porcellis
|
580 |
+
Jürgen Ovens
|
581 |
+
Juriaen Jacobsze
|
582 |
+
Juriaen van Streeck
|
583 |
+
Justus van Huysum
|
584 |
+
Karel Dujardin
|
585 |
+
Karel Slabbaert
|
586 |
+
Karel van der Pluym
|
587 |
+
Karel van Mander
|
588 |
+
Karel van Mander III
|
589 |
+
Karel van Mander the Younger
|
590 |
+
Krzysztof Lubieniecki
|
591 |
+
Lambert Doomer
|
592 |
+
Lambert Jacobsz
|
593 |
+
Laurens Craen
|
594 |
+
Leendert van Beijeren
|
595 |
+
Leendert van der Cooghen
|
596 |
+
Leonaert Bramer
|
597 |
+
Leonard Knijff
|
598 |
+
Lieve Verschuier
|
599 |
+
Lodewijk van der Helst
|
600 |
+
Louis-Abraham van Loo
|
601 |
+
Ludolf Bakhuizen
|
602 |
+
Ludolf de Jongh
|
603 |
+
Ludowyk Smits
|
604 |
+
Maerten Boelema de Stomme
|
605 |
+
Magdalena van den Hecken
|
606 |
+
Marcellus Laroon
|
607 |
+
Marcus de Bye
|
608 |
+
Margaretha de Heer
|
609 |
+
Margaretha van Godewijk
|
610 |
+
Maria de Grebber
|
611 |
+
Maria Schalcken
|
612 |
+
Maria Sibylla Merian
|
613 |
+
Maria van Oosterwijck
|
614 |
+
Maria Withoos
|
615 |
+
Marten Heemskerck van der Heck
|
616 |
+
Martin Mijtens the Elder
|
617 |
+
Martinus Lengele
|
618 |
+
Martinus Nellius
|
619 |
+
Martin Zaagmolen
|
620 |
+
Mathieu Dubus
|
621 |
+
Mattheus Wijtmans
|
622 |
+
Matthias Jansz van den Bergh
|
623 |
+
Matthias Stom
|
624 |
+
Matthias Withoos
|
625 |
+
Matthijs Harings
|
626 |
+
Matthijs Naiveu
|
627 |
+
Matthijs Wulfraet
|
628 |
+
Meindert Hobbema
|
629 |
+
Melchior d'Hondecoeter
|
630 |
+
Michiel Carree
|
631 |
+
Michiel Jansz. van Mierevelt
|
632 |
+
Michiel Maddersteg
|
633 |
+
Michiel Nouts
|
634 |
+
Michiel van Musscher
|
635 |
+
Moses ter Borch
|
636 |
+
Moses van Uyttenbroeck
|
637 |
+
Nicolaas Piemont
|
638 |
+
Nicolaas Roosendael
|
639 |
+
Nicolaes de Giselaer
|
640 |
+
Nicolaes de Helt Stockade
|
641 |
+
Nicolaes de Kemp
|
642 |
+
Nicolaes de Vree
|
643 |
+
Nicolaes Gillis
|
644 |
+
Nicolaes Hals
|
645 |
+
Nicolaes Lachtropius
|
646 |
+
Nicolaes Lastman
|
647 |
+
Nicolaes Latombe
|
648 |
+
Nicolaes Maes
|
649 |
+
Nicolaes Molenaer
|
650 |
+
Nicolaes Pickenoy
|
651 |
+
Nicolaes Pieterszoon Berchem
|
652 |
+
Nicolaes van Gelder
|
653 |
+
Nicolaes Willingh
|
654 |
+
Nicolas van Houy
|
655 |
+
Nikolaus Knüpfer
|
656 |
+
N.L. Peschier
|
657 |
+
Otto Hoynck
|
658 |
+
Otto Marseus van Schrieck
|
659 |
+
Otto van Veen
|
660 |
+
Palamedes Palamedesz.
|
661 |
+
Paulus Bor
|
662 |
+
Paulus Moreelse
|
663 |
+
Paulus Potter
|
664 |
+
Pauwels van Hillegaert
|
665 |
+
Peter Danckerts de Rij
|
666 |
+
Peter Lely
|
667 |
+
Peter Wtewael
|
668 |
+
Petrus Staverenus
|
669 |
+
Philip de Koninck
|
670 |
+
Philips Angel I
|
671 |
+
Philips Angel II
|
672 |
+
Philips Wouwerman
|
673 |
+
Philip Tideman
|
674 |
+
Pieter Anthonisz. van Groenewegen
|
675 |
+
Pieter Borsseler
|
676 |
+
Pieter Claesz
|
677 |
+
Pieter Codde
|
678 |
+
Pieter Coopse
|
679 |
+
Pieter Cornelisz van Rijck
|
680 |
+
Pieter Cornelisz van Slingelandt
|
681 |
+
Pieter Cornelisz van Soest
|
682 |
+
Pieter Cornelisz Verbeeck
|
683 |
+
Pieter Crijnse Volmarijn
|
684 |
+
Pieter de Bloot
|
685 |
+
Pieter de Grebber
|
686 |
+
Pieter de Hooch
|
687 |
+
Pieter de Molijn
|
688 |
+
Pieter de Neyn
|
689 |
+
Pieter de Putter
|
690 |
+
Pieter de Ring
|
691 |
+
Pieter de Ruelles
|
692 |
+
Pieter de Valck
|
693 |
+
Pieter de Zeelander
|
694 |
+
Pieter Dircksz Santvoort
|
695 |
+
Pieter Donker
|
696 |
+
Pieter Feddes van Harlingen
|
697 |
+
Pieter Fris
|
698 |
+
Pieter Gallis
|
699 |
+
Pieter Gerritsz van Roestraten
|
700 |
+
Pieter Hermansz Verelst
|
701 |
+
Pieter Holsteyn I
|
702 |
+
Pieter Holsteyn II
|
703 |
+
Pieter Isaacsz
|
704 |
+
Pieter Jacobsz. Duyfhuysen
|
705 |
+
Pieter Janssens Elinga
|
706 |
+
Pieter Jansz
|
707 |
+
Pieter Jansz. Saenredam
|
708 |
+
Pieter Jansz van Asch
|
709 |
+
Pieter Jansz van Ruyven
|
710 |
+
Pieter Lastman
|
711 |
+
Pieter Leermans
|
712 |
+
Pieter Legouch
|
713 |
+
Pieter Moninckx
|
714 |
+
Pieter Mulier II
|
715 |
+
Pieter Mulier the Elder
|
716 |
+
Pieter Nason
|
717 |
+
Pieter Nijs
|
718 |
+
Pieter Peutemans
|
719 |
+
Pieter Pietersz II
|
720 |
+
Pieter Pietersz Nedek
|
721 |
+
Pieter Post
|
722 |
+
Pieter Quast
|
723 |
+
Pieter Soutman
|
724 |
+
Pieter Steenwijck
|
725 |
+
Pieter Symonsz Potter
|
726 |
+
Pieter van Anraedt
|
727 |
+
Pieter van Berendrecht
|
728 |
+
Pieter van Bronckhorst
|
729 |
+
Pieter van den Bosch
|
730 |
+
Pieter van der Hulst
|
731 |
+
Pieter van der Leeuw
|
732 |
+
Pieter van der Werff
|
733 |
+
Pieter van Laer
|
734 |
+
Pieter van Mierevelt
|
735 |
+
Pieter van Noort
|
736 |
+
Pieter Verhoek
|
737 |
+
Pieter Withoos
|
738 |
+
Pieter Wouwerman
|
739 |
+
Quirijn van Brekelenkam
|
740 |
+
Rafaël Govertsz Camphuysen
|
741 |
+
Reinier Nooms
|
742 |
+
Rembrandt
|
743 |
+
Reyer Claesz Suycker
|
744 |
+
Reyer van Blommendael
|
745 |
+
Reynier Covyn
|
746 |
+
Reynier Hals
|
747 |
+
Reynier van Gherwen
|
748 |
+
Richard Brakenburgh
|
749 |
+
Richard van Bleeck
|
750 |
+
Robbert Duval
|
751 |
+
Rochus van Veen
|
752 |
+
Roeland van Laer
|
753 |
+
Roelant Roghman
|
754 |
+
Roelant Savery
|
755 |
+
Roelof Jansz van Vries
|
756 |
+
Roelof Koets
|
757 |
+
Roger de Piles' artists from Germany and the Low Countries
|
758 |
+
Rombout van Troyen
|
759 |
+
Romeyn de Hooghe
|
760 |
+
Salomon de Bray
|
761 |
+
Salomon Koninck
|
762 |
+
Salomon Mesdach
|
763 |
+
Salomon Rombouts
|
764 |
+
Salomon van Ruysdael
|
765 |
+
Samuel Dirksz van Hoogstraten
|
766 |
+
Sara Saftleven
|
767 |
+
Sara van Baalbergen
|
768 |
+
Simon de Vlieger
|
769 |
+
Simon Du Bois
|
770 |
+
Simon Germyn
|
771 |
+
Simon Kick
|
772 |
+
Simon Luttichuys
|
773 |
+
Simon Pietersz Verelst
|
774 |
+
Simon van der Does
|
775 |
+
Susanna van Steenwijk
|
776 |
+
Sybrand van Beest
|
777 |
+
Theodoor van Thulden
|
778 |
+
Theodor Roos
|
779 |
+
Theodor van der Schuer
|
780 |
+
Thomas de Keyser
|
781 |
+
Thomas Heeremans
|
782 |
+
Thomas Wijck
|
783 |
+
Tyman Arentsz. Cracht
|
784 |
+
Utrecht Caravaggism
|
785 |
+
Vincent van der Vinne
|
786 |
+
Vincenzo Armanno
|
787 |
+
Wallerant Vaillant
|
788 |
+
Warnard van Rijsen
|
789 |
+
Werner van den Valckert
|
790 |
+
Wilhelm Breckvelt
|
791 |
+
Wilhelmus Beurs
|
792 |
+
Willem Bartsius
|
793 |
+
Willem Claesz. Heda
|
794 |
+
Willem Cornelisz Duyster
|
795 |
+
Willem de Heusch
|
796 |
+
Willem de Poorter
|
797 |
+
Willem Doudijns
|
798 |
+
Willem Drost
|
799 |
+
Willem Eversdijck
|
800 |
+
Willem Frederiksz van Royen
|
801 |
+
Willem Gillisz Kool
|
802 |
+
Willem Hendrik Wilhelmus van Royen
|
803 |
+
Willem Hondius
|
804 |
+
Willem Jacobsz Delff
|
805 |
+
Willem Kalf
|
806 |
+
Willem Ormea
|
807 |
+
Willem Pieterszoon Buytewech
|
808 |
+
Willem Romeyn
|
809 |
+
Willem Schellinks
|
810 |
+
Willem van Aelst
|
811 |
+
Willem van Bemmel
|
812 |
+
Willem van den Bundel
|
813 |
+
Willem van der Vliet
|
814 |
+
Willem van de Velde the Elder
|
815 |
+
Willem van de Velde the Younger
|
816 |
+
Willem van Diest
|
817 |
+
Willem van Drielenburg
|
818 |
+
Willem van Honthorst
|
819 |
+
Willem van Ingen
|
820 |
+
Willem van Nieulandt II
|
821 |
+
Willem Verschuring
|
822 |
+
Willem Wissing
|
823 |
+
William Gouw Ferguson
|
824 |
+
Wouter Crabeth II
|
825 |
+
Wouter Knijff
|
826 |
+
Wybrand de Geest
|
827 |
+
Zacharias Blyhooft
|
828 |
+
Zacharias Paulusz
|
ex/dynamic-prompts/collections/artists/European Art/baroque/flemish_baroque_painters.txt
ADDED
@@ -0,0 +1,199 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Abraham Brueghel
|
2 |
+
Abraham Casembroot
|
3 |
+
Abraham Genoels
|
4 |
+
Abraham Godijn
|
5 |
+
Abraham Govaerts
|
6 |
+
Abraham van Blijenberch
|
7 |
+
Abraham van Diepenbeeck
|
8 |
+
Adam de Colone
|
9 |
+
Adam de Coster
|
10 |
+
Adriaen Brouwer
|
11 |
+
Adriaen de Bie
|
12 |
+
Adriaen Frans Boudewijns
|
13 |
+
Adriaen van Bloemen
|
14 |
+
Albert Flamen
|
15 |
+
Alexander Adriaenssen
|
16 |
+
Alexander Casteels the Elder
|
17 |
+
Alexander Casteels the Younger
|
18 |
+
Alexander Coosemans
|
19 |
+
Ambrosius Bosschaert
|
20 |
+
Ambrosius Brueghel
|
21 |
+
Andries Benedetti
|
22 |
+
Andries Bosman
|
23 |
+
Andries Daniels
|
24 |
+
Andries de Coninck
|
25 |
+
Andries van Eertvelt
|
26 |
+
Anna Francisca de Bruyns
|
27 |
+
Anthonie Crussens
|
28 |
+
Anthony van Dyck
|
29 |
+
Anton Goubau
|
30 |
+
Anton Gunther Gheringh
|
31 |
+
Antwerp school
|
32 |
+
Artus Claessens
|
33 |
+
Augustin Coppens
|
34 |
+
Bamboccianti
|
35 |
+
Bentvueghels
|
36 |
+
Bernaert de Bridt
|
37 |
+
Bertholet Flemalle
|
38 |
+
Carel Fonteyn
|
39 |
+
Carel van Falens
|
40 |
+
Charles Emmanuel Biset
|
41 |
+
Christoffel van den Berghe
|
42 |
+
Constantijn Francken
|
43 |
+
Cornelis Bol
|
44 |
+
Cornelis de Baellieur
|
45 |
+
Cornelis de Bryer
|
46 |
+
Cornelis Norbertus Gijsbrechts
|
47 |
+
Daniel van den Dyck
|
48 |
+
David de Coninck
|
49 |
+
Diego de Borgraf
|
50 |
+
Dominicus Claessens
|
51 |
+
Elias van den Broeck
|
52 |
+
Engelbert Ergo
|
53 |
+
Erasmus de Bie
|
54 |
+
Ferdinand van Apshoven the Elder
|
55 |
+
Ferdinand van Apshoven the Younger
|
56 |
+
Franciscus Gijsbrechts
|
57 |
+
Franciscus Hamers
|
58 |
+
François Duchatel
|
59 |
+
Frans Badens
|
60 |
+
Frans Cuyck van Myerop
|
61 |
+
Frans Denys
|
62 |
+
Frans Francken III
|
63 |
+
Frans Francken the Younger
|
64 |
+
Frans Geffels
|
65 |
+
Frans van Everbroeck
|
66 |
+
Frederik Bouttats the Elder
|
67 |
+
Gaspar de Crayer
|
68 |
+
Gaspar van Eyck
|
69 |
+
George Geldorp
|
70 |
+
Gérard Edelinck
|
71 |
+
Gilles Hallet
|
72 |
+
Gilliam Dandoy
|
73 |
+
Gillis Backereel
|
74 |
+
Gillis II Coignet
|
75 |
+
Godfriedt van Bochoutt
|
76 |
+
Gommaert van der Gracht
|
77 |
+
Gonzales Coques
|
78 |
+
Gonzales Franciscus Casteels
|
79 |
+
Gualterus Gysaerts
|
80 |
+
Guglielmo Borremans
|
81 |
+
Guillam Forchondt the Elder
|
82 |
+
G. van Deynum
|
83 |
+
Hendrick Andriessen
|
84 |
+
Hendrick de Clerck
|
85 |
+
Hendrick van Balen the Elder
|
86 |
+
Hendrik van der Borcht the elder
|
87 |
+
Hieronymus Francken II
|
88 |
+
Hieronymus Francken III
|
89 |
+
Hieronymus Galle
|
90 |
+
Ignatius Croon
|
91 |
+
Isabella Francken
|
92 |
+
Izaak Godijn
|
93 |
+
Jacob Caproens
|
94 |
+
Jacob de Bie
|
95 |
+
Jacob de Formentrou
|
96 |
+
Jacob Denys
|
97 |
+
Jacob Foppens van Es
|
98 |
+
Jacob Franquart
|
99 |
+
Jacob Peter Gowy
|
100 |
+
Jacques Backereel
|
101 |
+
Jacques d'Arthois
|
102 |
+
Jacques de l'Ange
|
103 |
+
Jacques Fouquier
|
104 |
+
Jan Anthonie Coxie
|
105 |
+
Jan Anton van der Baren
|
106 |
+
Jan Baptist Boel the Younger
|
107 |
+
Jan Baptist Bonnecroy
|
108 |
+
Jan Baptist Borrekens
|
109 |
+
Jan Baptist Bosschaert
|
110 |
+
Jan Baptist Brueghel
|
111 |
+
Jan Baptist de Crépu
|
112 |
+
Jan Baptist van Deynum
|
113 |
+
Jan Boeckhorst
|
114 |
+
Jan Brueghel the Elder
|
115 |
+
Jan Brueghel the Younger
|
116 |
+
Jan Carel van Eyck
|
117 |
+
Jan Cossiers
|
118 |
+
Jan Coxie
|
119 |
+
Jan de Herdt
|
120 |
+
Jan Dirven
|
121 |
+
Jan Frans van Bloemen
|
122 |
+
Jan Fyt
|
123 |
+
Jan Pauwel Gillemans the Elder
|
124 |
+
Jan Pauwel Gillemans the Younger
|
125 |
+
Jan Pieter Brueghel
|
126 |
+
Jan van Balen
|
127 |
+
Jan van Buken
|
128 |
+
Jan van Dalen
|
129 |
+
Jan van den Hecke
|
130 |
+
Jan van Essen
|
131 |
+
Jasper Broers
|
132 |
+
Jasper Geeraards
|
133 |
+
Jean Baptiste Assenede
|
134 |
+
Jean Baptiste de Champaigne
|
135 |
+
Jean Ducamps
|
136 |
+
Jean-Guillaume Carlier
|
137 |
+
Joannes de Cordua
|
138 |
+
Joannes van der Brugghen
|
139 |
+
Johann Baptiste Bouttats
|
140 |
+
Joos van Craesbeeck
|
141 |
+
Joris van Bredael
|
142 |
+
Laureys a Castro
|
143 |
+
Lodewijk de Vadder
|
144 |
+
Louis de Caullery
|
145 |
+
Louis Finson
|
146 |
+
Lucas Achtschellinck
|
147 |
+
Lucas Franchoys the Elder
|
148 |
+
Lucas Franchoys the Younger
|
149 |
+
Marcus Gheeraerts the Younger
|
150 |
+
Marie Duchatel
|
151 |
+
Melchior Hamers
|
152 |
+
Michel Bouillon
|
153 |
+
Michele Desubleo
|
154 |
+
Michiel II Coignet
|
155 |
+
Nicasius Bernaerts
|
156 |
+
Nicolaas van Eyck
|
157 |
+
Nicolaes Cave
|
158 |
+
Norbert van Bloemen
|
159 |
+
Osias Beert
|
160 |
+
Ottmar Elliger
|
161 |
+
Pauwels Casteels
|
162 |
+
Pedro de Campolargo
|
163 |
+
Peeter Gijsels
|
164 |
+
Peeter van Bredael
|
165 |
+
Peter Franchoys
|
166 |
+
Peter Frans Casteels
|
167 |
+
Peter van Boucle
|
168 |
+
Peter van Halen
|
169 |
+
Philip Fruytiers
|
170 |
+
Philip Gyselaer
|
171 |
+
Philippe de Champaigne
|
172 |
+
Philips Brueghel
|
173 |
+
Philip van Dapels
|
174 |
+
Pieter Boel
|
175 |
+
Pieter Bout
|
176 |
+
Pieter Brueghel the Younger
|
177 |
+
Pieter Casteels II
|
178 |
+
Pieter Hardimé
|
179 |
+
Pieter van Aelst
|
180 |
+
Pieter van Avont
|
181 |
+
Pieter van Bloemen
|
182 |
+
Pieter van der Borcht
|
183 |
+
Sebastiaen van Aken
|
184 |
+
Sebastian Castro
|
185 |
+
Simon Ardé
|
186 |
+
Simon Hardimé
|
187 |
+
Simon Johannes van Douw
|
188 |
+
Theodoor Aenvanck
|
189 |
+
Theodoor Boeyermans
|
190 |
+
Thomas van Apshoven
|
191 |
+
Vigor Boucquet
|
192 |
+
Vincent Adriaenssen
|
193 |
+
Vincenzo Armanno
|
194 |
+
Walther Damery
|
195 |
+
Wenceslas Cobergher
|
196 |
+
Wilhelm Schubert van Ehrenberg
|
197 |
+
Willem Backereel
|
198 |
+
Willem Gabron
|
199 |
+
Willem van Haecht
|
ex/dynamic-prompts/collections/artists/European Art/baroque/french_baroque_painters.txt
ADDED
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Charles Errard
|
2 |
+
Charles Le Brun
|
3 |
+
Charles Mellin
|
4 |
+
Claude Deruet
|
5 |
+
Claude-Guy Hallé
|
6 |
+
Claude Lorrain
|
7 |
+
Claude Mellan
|
8 |
+
Daniel Hallé
|
9 |
+
Eustache Le Sueur
|
10 |
+
Francisque Millet
|
11 |
+
François de Nomé
|
12 |
+
François de Troy
|
13 |
+
François Perrier
|
14 |
+
François Puget
|
15 |
+
François Stella
|
16 |
+
Gaspard Dughet
|
17 |
+
Georges de La Tour
|
18 |
+
Henri Testelin
|
19 |
+
Hyacinthe Rigaud
|
20 |
+
Isaac Oliver
|
21 |
+
Jacob van Schuppen
|
22 |
+
Jacques Blanchard
|
23 |
+
Jacques d'Agar
|
24 |
+
Jacques des Rousseaux
|
25 |
+
Jacques Restout
|
26 |
+
Jacques Stella
|
27 |
+
Jean Bérain the Elder
|
28 |
+
Jean de Beaugrand
|
29 |
+
Jean Jouvenet
|
30 |
+
Jean LeClerc
|
31 |
+
Laurent de La Hyre
|
32 |
+
Le Nain
|
33 |
+
Louis-Abraham van Loo
|
34 |
+
Louis Cretey
|
35 |
+
Louise Moillon
|
36 |
+
Madeleine Boullogne
|
37 |
+
Michel Serre
|
38 |
+
Monsù Desiderio
|
39 |
+
Nicolas Guibal
|
40 |
+
Nicolas Mignard
|
41 |
+
Nicolas Poussin
|
42 |
+
Nicolas Tournier
|
43 |
+
Philippe de Champaigne
|
44 |
+
Pierre Bourguignon
|
45 |
+
Pierre Mignard
|
46 |
+
Pierre Rabon
|
47 |
+
Pieter Dubordieu
|
48 |
+
Quentin Varin
|
49 |
+
Raymond Lafage
|
50 |
+
Sebastian Stoskopff
|
51 |
+
Sébastien Bourdon
|
52 |
+
Simon Vouet
|
53 |
+
Trophime Bigot
|
54 |
+
Vincent Malo
|
ex/dynamic-prompts/collections/artists/European Art/baroque/german_baroque_painters.txt
ADDED
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Anna Katharina Block
|
2 |
+
Anton Mirou
|
3 |
+
Benjamin Block
|
4 |
+
Bentvueghels
|
5 |
+
Christian Berentz
|
6 |
+
Christopher Paudiß
|
7 |
+
Cosmas Damian Asam
|
8 |
+
Daniel Blok
|
9 |
+
David Klöcker Ehrenstrahl
|
10 |
+
Ernst Stuven
|
11 |
+
Franz Joachim Beich
|
12 |
+
Franz Ludwig Raufft
|
13 |
+
Franz Werner von Tamm
|
14 |
+
Franz Wulfhagen
|
15 |
+
Georg Anton Urlaub
|
16 |
+
Georg Hainz
|
17 |
+
Godfrey Kneller
|
18 |
+
Hendrik van der Borcht II
|
19 |
+
Hendrik van der Borcht the elder
|
20 |
+
Isaak Soreau
|
21 |
+
Jacob Christoph Le Blon
|
22 |
+
Jacob Ernst Thomann von Hagelstein
|
23 |
+
Jacob Marrel
|
24 |
+
Jan Boeckhorst
|
25 |
+
Joachim von Sandrart
|
26 |
+
Johann Baptist Zimmermann
|
27 |
+
Johann Carl Loth
|
28 |
+
Johannes Spilberg
|
29 |
+
Johann Georg Fischer
|
30 |
+
Johann Georg Melchior Schmidtner
|
31 |
+
Johann Georg Stuhr
|
32 |
+
Johann Heinrich Roos
|
33 |
+
Johann Hulsman
|
34 |
+
Johann Liss
|
35 |
+
Johann Melchior Roos
|
36 |
+
Johann Oswald Harms
|
37 |
+
Johann Ulrich Mayr
|
38 |
+
Johann Wilhelm Baur
|
39 |
+
Johann Zacharias Kneller
|
40 |
+
Joseph Anton Merz
|
41 |
+
Joseph Ignaz Appiani
|
42 |
+
Jürgen Ovens
|
43 |
+
Louise Hollandine of the Palatinate
|
44 |
+
Ludolf Bakhuizen
|
45 |
+
Maria Dorothea Wagner
|
46 |
+
Maria Sibylla Merian
|
47 |
+
Matthias Scheits
|
48 |
+
Michael Conrad Hirt
|
49 |
+
Michael Willmann
|
50 |
+
Nikolaus Knüpfer
|
51 |
+
Ottmar Elliger
|
52 |
+
Philipp Peter Roos
|
53 |
+
Philip Tideman
|
54 |
+
Pieter Schoubroeck
|
55 |
+
Salomon Adler
|
56 |
+
Sebastian Stoskopff
|
57 |
+
Simon Peter Tilemann
|
58 |
+
Susanna Mayr
|
59 |
+
Theodor Roos
|
60 |
+
Willem van Bemmel
|
ex/dynamic-prompts/collections/artists/European Art/baroque/greek_baroque_painters.txt
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Belisario Corenzio
|
2 |
+
Efstathios Karousos
|
3 |
+
Elias Moskos
|
4 |
+
Emmanuel Tzanes
|
5 |
+
Ioannis Korais
|
6 |
+
Konstantinos Tzanes
|
7 |
+
Nikolaos Doxaras
|
8 |
+
Nikolaos Kallergis
|
9 |
+
Nikolaos Koutouzis
|
10 |
+
Panagiotis Doxaras
|
11 |
+
Philotheos Skoufos
|
12 |
+
Spiridione Roma
|
13 |
+
Theodore Poulakis
|
ex/dynamic-prompts/collections/artists/European Art/baroque/italian_baroque_painters.txt
ADDED
@@ -0,0 +1,198 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Agostino Beltrano
|
2 |
+
Agostino Bonisoli
|
3 |
+
Alessandro Albini
|
4 |
+
Alessandro Badiale
|
5 |
+
Alessandro Baratta
|
6 |
+
Alessandro Bardelli
|
7 |
+
Alfonso Aldiverti
|
8 |
+
Ambrogio Besozzi
|
9 |
+
Andrea Barbiani
|
10 |
+
Andrea Belvedere
|
11 |
+
Andrea dell'Asta
|
12 |
+
Angelica Veronica Airola
|
13 |
+
Aniella di Beltrano
|
14 |
+
Aniello Ascione
|
15 |
+
Anton Domenico Bamberini
|
16 |
+
Anton Giuseppe Barbazza
|
17 |
+
Antonia Bertucci-Pinelli
|
18 |
+
Antonio Amorosi
|
19 |
+
Antonio Bacci
|
20 |
+
Antonio Baldi
|
21 |
+
Antonio Balestra
|
22 |
+
Antonio Barbalonga
|
23 |
+
Antonio Baroni
|
24 |
+
Antonio Bellucci
|
25 |
+
Antonio Beltrami
|
26 |
+
Antonio Bonfanti
|
27 |
+
Antonio de Bellis
|
28 |
+
Atanasio Bimbacci
|
29 |
+
Aurelio Barili
|
30 |
+
Baldassare Aloisi
|
31 |
+
Baldassare Bianchi
|
32 |
+
Bartolomeo Baderna
|
33 |
+
Bartolomeo Barbiani
|
34 |
+
Bartolomeo Bassi
|
35 |
+
Bartolomeo Bettera
|
36 |
+
Bartolomeo Biscaino
|
37 |
+
Benedetto Bandiera
|
38 |
+
Bernardino Bono
|
39 |
+
Camillo Berlinghieri
|
40 |
+
Carlo Amalfi
|
41 |
+
Carlo Ascenzi
|
42 |
+
Carlo Biffi
|
43 |
+
Carlo Bolognini
|
44 |
+
Carlo Girolamo Bersotti
|
45 |
+
Ciro Adolfi
|
46 |
+
Clemente Bocciardo
|
47 |
+
Dionisio Boldo
|
48 |
+
Domenico Ambrogi
|
49 |
+
Domenico Bettini
|
50 |
+
Domenico Bocciardo
|
51 |
+
Domenico de Benedettis
|
52 |
+
Domenico Maria Bonavera
|
53 |
+
Ercole Bazzicaluva
|
54 |
+
Ercole Gaetano Bertuzzi
|
55 |
+
Faustino Bocchi
|
56 |
+
Federico Bencovich
|
57 |
+
Federico Bianchi
|
58 |
+
Ferrante Amendola
|
59 |
+
Ferrante Bacciocchi
|
60 |
+
Filippo Abbiati
|
61 |
+
Filippo d'Angeli
|
62 |
+
Fra Bonaventura Bisi
|
63 |
+
Francesco Albani
|
64 |
+
Francesco Allegrini da Gubbio
|
65 |
+
Francesco Ange
|
66 |
+
Francesco Antonozzi
|
67 |
+
Francesco Appiani
|
68 |
+
Francesco Aviani
|
69 |
+
Francesco Barbieri
|
70 |
+
Francesco Bassi
|
71 |
+
Francesco Bernardi
|
72 |
+
Francesco Boccaccino
|
73 |
+
Francesco Bonifaccio
|
74 |
+
Francesco Borgani
|
75 |
+
Gennaro Basile
|
76 |
+
Giacinto Bellini
|
77 |
+
Giacinto Boccanera
|
78 |
+
Giacomo Adolfi
|
79 |
+
Giacomo Alberelli
|
80 |
+
Giacomo Alboresi
|
81 |
+
Giacomo Antonio Arland
|
82 |
+
Giacomo Anziani
|
83 |
+
Giacomo Apollonio
|
84 |
+
Giacomo Argente
|
85 |
+
Giacomo Bargone
|
86 |
+
Giacomo Barri
|
87 |
+
Giacomo Bolognini
|
88 |
+
Giacomo Boni
|
89 |
+
Gian Lorenzo Bernini
|
90 |
+
Gioacchino Assereto
|
91 |
+
Giorgio Alberino
|
92 |
+
Gioseffo Maria Bartolini
|
93 |
+
Giovanni Andrea Ansaldo
|
94 |
+
Giovanni Andrea Biscaino
|
95 |
+
Giovanni Andrea Podestà
|
96 |
+
Giovanni Baglione
|
97 |
+
Giovanni Battista Alberoni
|
98 |
+
Giovanni Battista Amigazzi
|
99 |
+
Giovanni Battista Baiardo
|
100 |
+
Giovanni Battista Barbiani
|
101 |
+
Giovanni Battista Barca
|
102 |
+
Giovanni Battista Belloti
|
103 |
+
Giovanni Battista Benaschi
|
104 |
+
Giovanni Battista Bertusio
|
105 |
+
Giovanni Battista Bolognini
|
106 |
+
Giovanni Battista Bonacina
|
107 |
+
Giovanni Bernardino Azzolini
|
108 |
+
Giovanni Biliverti
|
109 |
+
Giovanni Carlo Aliberti
|
110 |
+
Giovanni Francesco Bagnoli
|
111 |
+
Giovanni Francesco Bassotti
|
112 |
+
Giovanni Giacomo Barbelli
|
113 |
+
Giovanni Girolamo Bonesi
|
114 |
+
Giovanni Lorenzo Bertolotti
|
115 |
+
Giovanni Raffaele Badaracco
|
116 |
+
Giovenale Boetto
|
117 |
+
Girolamo Bonini
|
118 |
+
Giulio Benso
|
119 |
+
Giulio Cesare Angeli
|
120 |
+
Giulio Cesare Begni
|
121 |
+
Giulio Giacinto Avellino
|
122 |
+
Giuseppe Agellio
|
123 |
+
Giuseppe Alberti
|
124 |
+
Giuseppe Angeli
|
125 |
+
Giuseppe Angelini
|
126 |
+
Giuseppe Arrighi
|
127 |
+
Giuseppe Avanzi
|
128 |
+
Giuseppe Badaracco
|
129 |
+
Giuseppe Bazzani
|
130 |
+
Giuseppe Bonati
|
131 |
+
Giuseppe Bonito
|
132 |
+
Guido Ubaldo Abbatini
|
133 |
+
Isidoro Bianchi
|
134 |
+
Jacopo Baccarini
|
135 |
+
Jacopo Bambini
|
136 |
+
Jacopo Barbello
|
137 |
+
Kaspar Anton von Baroni-Cavalcabo
|
138 |
+
Laura Bernasconi
|
139 |
+
Lazzaro Baldi
|
140 |
+
Leonardo dell'Arca
|
141 |
+
Lionello Bononi
|
142 |
+
Lodovico Bertucci
|
143 |
+
Lorenzo Bergonzoni
|
144 |
+
Luca Antonio Bistega
|
145 |
+
Luca Barbieri
|
146 |
+
Luigi Baccio del Bianco
|
147 |
+
Marcantonio Bellavia
|
148 |
+
Marco Antonio Bassetti
|
149 |
+
Marco Bandinelli
|
150 |
+
Maria Maddalena Baldacci
|
151 |
+
Mario Balassi
|
152 |
+
Martino Altomonte
|
153 |
+
Matteo Bonechi
|
154 |
+
Matteo Borboni
|
155 |
+
Mattia Battini
|
156 |
+
Mattia Benedetti
|
157 |
+
Mauro Aldrovandini
|
158 |
+
Michele Blasco
|
159 |
+
Niccolò Bambini
|
160 |
+
Niccolò Berrettoni
|
161 |
+
Niccolò Billy
|
162 |
+
Nicola Bertucci
|
163 |
+
Onofrio Avellino
|
164 |
+
Orazio Bianchi
|
165 |
+
Ottavio Amigoni
|
166 |
+
Paolo Albertoni
|
167 |
+
Paolo Alboni
|
168 |
+
Paolo Anesi
|
169 |
+
Paolo Antonio Barbieri
|
170 |
+
Paolo Bianchi
|
171 |
+
Paolo Biancucci
|
172 |
+
Paolo Bonomino
|
173 |
+
Paolo Emilio Besenzi
|
174 |
+
Paolo Vincenzo Bonomini
|
175 |
+
Pasquale Bellonio
|
176 |
+
Pier Francesco Battistelli
|
177 |
+
Piermaria Bagnadore
|
178 |
+
Pietro Adami
|
179 |
+
Pietro Andrea Barbieri Pucciardi
|
180 |
+
Pietro Antonio Avanizi
|
181 |
+
Pietro Antonio Avanzini
|
182 |
+
Pietro Aquila
|
183 |
+
Pietro Avogadro
|
184 |
+
Pietro Bellotti
|
185 |
+
Pietro Bianchi
|
186 |
+
Pietro Francesco Alberti
|
187 |
+
Pietro Paolo Baldini
|
188 |
+
Pietro Paolo Bonzi
|
189 |
+
Pompeo Aldrovandini
|
190 |
+
Scipione Angelini
|
191 |
+
Sebastiano Bombelli
|
192 |
+
Simone Barabino
|
193 |
+
Sisto Badalocchio
|
194 |
+
Stefano Amadei
|
195 |
+
Tiburzio Baldini
|
196 |
+
Tommaso Aldrovandini
|
197 |
+
Valerio Baldassari
|
198 |
+
Vittorio Bigari
|
ex/dynamic-prompts/collections/artists/European Art/baroque/netherlandish_baroque_painters.txt
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
__dutch_goldenage_painters__
|
2 |
+
__bentvueghels__
|
ex/dynamic-prompts/collections/artists/European Art/baroque/quadratura.txt
ADDED
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Agostino Carlini
|
2 |
+
Agostino Collaceroni
|
3 |
+
Agostino Mitelli
|
4 |
+
Alberto Carlieri
|
5 |
+
Alessandro Baratta
|
6 |
+
Angelo Michele Colonna
|
7 |
+
Antonio Bonetti
|
8 |
+
Antonio Maria Panni
|
9 |
+
Antonio Rolli
|
10 |
+
Baldassare Bianchi
|
11 |
+
Bartolo Ceru
|
12 |
+
Bartolomeo Bassi
|
13 |
+
Carlo Bolognini
|
14 |
+
Carlo Moscatiello
|
15 |
+
Cesare Baglioni
|
16 |
+
Cristoforo Rosa
|
17 |
+
Domenico Ambrogi
|
18 |
+
Domenico Bruni
|
19 |
+
Domenico Carnovale
|
20 |
+
Domenico Ghislandi
|
21 |
+
Domenico Santi
|
22 |
+
Enrico Haffner
|
23 |
+
Faustino Trebbi
|
24 |
+
Filippo Maccari
|
25 |
+
Flaminio Innocenzo Minozzi
|
26 |
+
Francesco Costa
|
27 |
+
Francesco Quaini
|
28 |
+
Francesco Veau
|
29 |
+
Fra Simone da Carnuli
|
30 |
+
Gaetano Alemani
|
31 |
+
Gerolamo Mengozzi Colonna
|
32 |
+
Giacomo Alboresi
|
33 |
+
Giacomo Torelli
|
34 |
+
Giovanni Antonio Caldelli
|
35 |
+
Giovanni Battista Alberoni
|
36 |
+
Giovanni Battista Caccioli
|
37 |
+
Giovanni Battista Crosato
|
38 |
+
Giovanni Battista Gaulli
|
39 |
+
Giovanni Benedetto Paolazzi
|
40 |
+
Giovanni Giacomo Monti
|
41 |
+
Giovanni Maria Cerva
|
42 |
+
Giovanni Niccolò Servandoni
|
43 |
+
Giovanni Paderna
|
44 |
+
Girolamo Curti
|
45 |
+
Girolamo Pellizoni
|
46 |
+
Giulio Trogli
|
47 |
+
Giuseppe Alabardi
|
48 |
+
Giuseppe Antonio Landi
|
49 |
+
Giuseppe Dallamano
|
50 |
+
Giuseppe Melani
|
51 |
+
Giuseppe Natali
|
52 |
+
Giuseppe Turbini
|
53 |
+
Gregorio De Ferrari
|
54 |
+
Jacopo Antonio Mannini
|
55 |
+
Jacopo Chiavistelli
|
56 |
+
Lorenzo del Moro
|
57 |
+
Lorenzo Pavia
|
58 |
+
Luca Antonio Bistega
|
59 |
+
Luigi Quaini
|
60 |
+
Marcantonio Chiarini
|
61 |
+
Mattia Benedetti
|
62 |
+
Mauro Aldrovandini
|
63 |
+
Ottavio Viviani
|
64 |
+
Paolo Ballarini
|
65 |
+
Paolo Brozzi
|
66 |
+
Petronio Fancelli
|
67 |
+
Pier Francesco Battistelli
|
68 |
+
Pietro Anderlini
|
69 |
+
Pietro Capelli
|
70 |
+
Pietro Carattoli
|
71 |
+
Pietro Paltronieri
|
72 |
+
Rinaldo Botti
|
73 |
+
Stefano Orlandi
|
74 |
+
Tommaso Sandrino
|
ex/dynamic-prompts/collections/artists/European Art/baroque/rococco.txt
ADDED
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Adélaïde Victoire Hall
|
2 |
+
Alessandro Magnasco
|
3 |
+
Alexander Roslin
|
4 |
+
Andien de Clermont
|
5 |
+
Andrea Casali
|
6 |
+
Angelica Le Gru Perotti
|
7 |
+
Angelo Mozzillo
|
8 |
+
Anna Maria Hilfeling
|
9 |
+
Anna Rajecka
|
10 |
+
Antoine Watteau
|
11 |
+
Antonio Balestra
|
12 |
+
Antonio Beccadelli (painter)
|
13 |
+
Antonio Bellucci
|
14 |
+
Antonio Liozzi
|
15 |
+
Antonio Rossi (painter)
|
16 |
+
Balthasar Denner
|
17 |
+
Bartolomeo Nazari
|
18 |
+
Bartolomeo Pedon
|
19 |
+
Bellino Bellini
|
20 |
+
Carlo Carlone
|
21 |
+
Charles-Amédée-Philippe van Loo
|
22 |
+
Charles Joseph Flipart
|
23 |
+
Charles-Joseph Natoire
|
24 |
+
Corrado Giaquinto
|
25 |
+
Daniel Hisgen
|
26 |
+
Domenico Corvi
|
27 |
+
Elia Interguglielmi
|
28 |
+
Élisabeth Vigée Le Brun
|
29 |
+
Étienne Jeaurat
|
30 |
+
Flora Yukhnovich
|
31 |
+
Francescantonio Coratoli
|
32 |
+
Francesco Fernandi
|
33 |
+
Francesco Monti (Bologna)
|
34 |
+
Francesco Zugno
|
35 |
+
François Boucher
|
36 |
+
François Guérin (artist)
|
37 |
+
František Jakub Prokyš
|
38 |
+
Gaetano Gandolfi
|
39 |
+
Gaspare Traversi
|
40 |
+
Georgije Tenecki
|
41 |
+
Giambattista Pittoni
|
42 |
+
Giambettino Cignaroli
|
43 |
+
Giampietro Zanotti
|
44 |
+
Giorgio Anselmi
|
45 |
+
Giovanni Antonio Greccolini
|
46 |
+
Giovanni Battista Cipriani
|
47 |
+
Giovanni Battista Lorenzi (painter)
|
48 |
+
Giovanni Battista Tiepolo
|
49 |
+
Giovanni Domenico Cignaroli
|
50 |
+
Giovanni Domenico Ferretti
|
51 |
+
Giovanni Domenico Tiepolo
|
52 |
+
Giuseppe Baldrighi
|
53 |
+
Giuseppe Bazzani
|
54 |
+
Giuseppe Bonito
|
55 |
+
Giuseppe Dallamano
|
56 |
+
Giuseppe Marchesi
|
57 |
+
Giuseppe Nogari
|
58 |
+
Gottlieb Welté
|
59 |
+
Jacopo Amigoni
|
60 |
+
Jean-Baptiste Charpentier the Elder
|
61 |
+
Jean-Baptiste Pater
|
62 |
+
Jean-Baptiste Pillement
|
63 |
+
Jean-Baptiste-Siméon Chardin
|
64 |
+
Jean-Baptiste van Loo
|
65 |
+
Jean François de Troy
|
66 |
+
Jean-Honoré Fragonard
|
67 |
+
Johann Jakob Zeiller
|
68 |
+
Joseph Ignaz Appiani
|
69 |
+
François Boucher
|
70 |
+
Lorenzo Baldissera Tiepolo
|
71 |
+
Lorenzo De Caro
|
72 |
+
Louis-Jean-François Lagrenée
|
73 |
+
Louis-Michel van Loo
|
74 |
+
Marcello Leopardi
|
75 |
+
Margareta Christina Giers
|
76 |
+
Nicola Antonio Monti
|
77 |
+
Nicola Peccheneda
|
78 |
+
Paolo Anesi
|
79 |
+
Peter Adolf Hall
|
80 |
+
Pier Leone Ghezzi
|
81 |
+
Pietro Capelli
|
82 |
+
Placido Costanzi
|
83 |
+
Sebastiano Ricci
|
84 |
+
Thomas Gainsborough
|
85 |
+
Ulrika Pasch
|
86 |
+
William Delacour
|
ex/dynamic-prompts/collections/artists/European Art/baroque/spanish_baroque_painters.txt
ADDED
@@ -0,0 +1,157 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Agustín del Castillo
|
2 |
+
Agustin Gasull
|
3 |
+
Agustín Leonardo
|
4 |
+
Alardo de Popma
|
5 |
+
Alejandro de Loarte
|
6 |
+
Alejandro González Velázquez
|
7 |
+
Alonso de Llera Zambrano
|
8 |
+
Alonso Miguel de Tovar
|
9 |
+
Ambrosio Martínez Bustos
|
10 |
+
Andrea López Caballero
|
11 |
+
Andrés Amaya
|
12 |
+
Andrés Leyto
|
13 |
+
Andrés Marzo
|
14 |
+
Andrés Pérez
|
15 |
+
Antonio Bisquert
|
16 |
+
Antonio del Castillo y Saavedra
|
17 |
+
Antonio de Pereda
|
18 |
+
Antonio de Puga
|
19 |
+
Antonio Fernández Arias
|
20 |
+
Antonio González Velázquez
|
21 |
+
Antonio L'Horfelin
|
22 |
+
Antonio Palomino
|
23 |
+
Antonio Ponz
|
24 |
+
Antonio Richarte
|
25 |
+
Antonio Vela Cobo
|
26 |
+
Bartolomé Esteban Murillo
|
27 |
+
Bartolomé Pérez
|
28 |
+
Bartolomé Román
|
29 |
+
Benevides Juan Ramirez
|
30 |
+
Benito Manuel Agüero
|
31 |
+
Bernardo Germán de Llórente
|
32 |
+
Bernardo Polo
|
33 |
+
Blas de Ledesma
|
34 |
+
Buonaventura Ligli
|
35 |
+
Carlos Luis de Ribera y Fieve
|
36 |
+
Claudio Coello
|
37 |
+
Clemente de Torres
|
38 |
+
Cristóbal de León
|
39 |
+
Cristóbal de Villalpando
|
40 |
+
Cristóbal García Salmerón
|
41 |
+
Cristóbal López
|
42 |
+
Cristóbal Valero
|
43 |
+
Cristóbal Vela
|
44 |
+
Diego de Leyva
|
45 |
+
Diego Polo the Younger
|
46 |
+
Diego Velázquez
|
47 |
+
Diego Vidal de Liendo
|
48 |
+
Esteban Márquez de Velasco
|
49 |
+
Eugenio Caxés
|
50 |
+
Evaristo Muñoz
|
51 |
+
Felipe de León
|
52 |
+
Felipe Diricksen
|
53 |
+
Felipe Gil de Mena
|
54 |
+
Felipe Ramírez
|
55 |
+
Félix Castello
|
56 |
+
Fernando Márquez Joya
|
57 |
+
Francisco Agullo
|
58 |
+
Francisco Barrera
|
59 |
+
Francisco Caro
|
60 |
+
Francisco Collantes
|
61 |
+
Francisco de Aguirre
|
62 |
+
Francisco de Burgos Mantilla
|
63 |
+
Francisco de Reyna
|
64 |
+
Francisco de Zurbarán
|
65 |
+
Francisco Herrera the Elder
|
66 |
+
Francisco Llamas
|
67 |
+
Francisco Lopez Caro
|
68 |
+
Francisco Preciado
|
69 |
+
Francisco Rizi
|
70 |
+
Francisco Salmerón
|
71 |
+
Francisco Varela
|
72 |
+
Gerónimo Antonio de Ezquerra
|
73 |
+
Geronimo de Bobadilla
|
74 |
+
Gerónimo Ramírez
|
75 |
+
Giovanni Do
|
76 |
+
Gregorio Bausá
|
77 |
+
Ignacio de Iriarte
|
78 |
+
Ignacio de León Salcedo
|
79 |
+
Ignacio de Ries
|
80 |
+
Isaac Lievendal
|
81 |
+
Isidoro de Redondillo
|
82 |
+
Jaime López
|
83 |
+
Jaime Mosen Ponz
|
84 |
+
Jerónimo Jacinto de Espinosa
|
85 |
+
Joaquim Juncosa
|
86 |
+
Joaquín Inza y Ainsa
|
87 |
+
José Antolínez
|
88 |
+
José de Ledesma
|
89 |
+
Josefa de Óbidos
|
90 |
+
Josef Lopez
|
91 |
+
Josef Ramírez
|
92 |
+
José Leonardo
|
93 |
+
Jose Risueño
|
94 |
+
José Romeo
|
95 |
+
Juan Antonio García de Bouzas
|
96 |
+
Juan Antonio Ribera
|
97 |
+
Juan Bautista Maíno
|
98 |
+
Juan Bautista Martínez del Mazo
|
99 |
+
Juan Bautista Ravanals
|
100 |
+
Juan Caro de Tavira
|
101 |
+
Juan Carreño de Miranda
|
102 |
+
Juan de Alfaro y Gámez
|
103 |
+
Juan de Arellano
|
104 |
+
Juan de Espinosa
|
105 |
+
Juan del Castillo
|
106 |
+
Juan de Licalde
|
107 |
+
Juan de Loaysa y Giron
|
108 |
+
Juan de Peñalosa
|
109 |
+
Juan de Valdés Carasquilla
|
110 |
+
Juan de Valdés Leal
|
111 |
+
Juan Fernández el Labrador
|
112 |
+
Juan García de Miranda
|
113 |
+
Juan Martín Cabezalero
|
114 |
+
Juan Rizi
|
115 |
+
Juan Rodríguez Juárez
|
116 |
+
Juan Valdelmira de Leon
|
117 |
+
Juan van der Hamen
|
118 |
+
Juan Vicente Ribera
|
119 |
+
Jusepe de Ribera
|
120 |
+
Lorenzo Quiros
|
121 |
+
Lucas de Valdés
|
122 |
+
Luis González Velázquez
|
123 |
+
Luis Paret y Alcázar
|
124 |
+
Luis Tristán
|
125 |
+
Maria de Abarca
|
126 |
+
Mateo Cerezo
|
127 |
+
Mateo Gilarte
|
128 |
+
Miguel Posadas
|
129 |
+
Mosen Vicente Bru
|
130 |
+
Niccolò Granello
|
131 |
+
Nicolás de la Quadra
|
132 |
+
Nicolás de Villacis
|
133 |
+
Orazio Cambiasi
|
134 |
+
Pablo Legote
|
135 |
+
Pablo Pontons
|
136 |
+
Pablo Rabiella
|
137 |
+
Pedro Atanasio Bocanegra
|
138 |
+
Pedro de Campolargo
|
139 |
+
Pedro de Camprobín
|
140 |
+
Pedro de Moya
|
141 |
+
Pedro de Obregón
|
142 |
+
Pedro Orrente
|
143 |
+
Pedro Pozo
|
144 |
+
Pedro Ramírez
|
145 |
+
Pedro Rodriguez de Miranda
|
146 |
+
Roque Ponce
|
147 |
+
Sebastián de Llanos y Valdés
|
148 |
+
Sebastián Herrera Barnuevo
|
149 |
+
Simón de León Leal
|
150 |
+
Teodoro Ardemans
|
151 |
+
Tomas de Aguiar
|
152 |
+
Tomás Francisco Prieto
|
153 |
+
Tomás Yepes
|
154 |
+
Vicente Castelló
|
155 |
+
Vicente Giner
|
156 |
+
Vicente Guirri
|
157 |
+
Vincenzo Carducci
|
ex/dynamic-prompts/collections/artists/European Art/classical/classical.txt
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Minoan art
|
2 |
+
Aegean art
|
3 |
+
Cycladic art
|
4 |
+
Ancient Greek art
|
5 |
+
Mycenaean art
|
6 |
+
Cycladic art
|
7 |
+
Ancient Egyptian art
|
8 |
+
Roman Art
|
9 |
+
|
ex/dynamic-prompts/collections/artists/European Art/medieval/gothic.txt
ADDED
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Agostino di Giovanni
|
2 |
+
Albertus Pictor
|
3 |
+
Allegretto Nuzi
|
4 |
+
Altichiero
|
5 |
+
Andrea da Firenze
|
6 |
+
Andrea Pisano
|
7 |
+
André Beauneveu
|
8 |
+
Arnau Bassa
|
9 |
+
Arnolfo di Cambio
|
10 |
+
Bartolo di Fredi
|
11 |
+
Benedetto Antelami
|
12 |
+
Bernat Martorell
|
13 |
+
Bernt Notke
|
14 |
+
Bonaventura Berlinghieri
|
15 |
+
Bonino da Campione
|
16 |
+
Claus Sluter
|
17 |
+
Cola Petruccioli
|
18 |
+
Daniel Mauch
|
19 |
+
Duccio di Buoninsegna
|
20 |
+
Evrard d'Orleans
|
21 |
+
Ferrer Bassa
|
22 |
+
Fra Angelico
|
23 |
+
Fra Guglielmo
|
24 |
+
Gano di Fazio
|
25 |
+
Gentile da Fabriano
|
26 |
+
Gherardo Starnina
|
27 |
+
Gil de Siloé
|
28 |
+
Giottino
|
29 |
+
Giovanni Bon
|
30 |
+
Giovanni da Balduccio
|
31 |
+
Giovanni da Campione
|
32 |
+
Giovanni da Milano
|
33 |
+
Giovanni del Biondo
|
34 |
+
Giovanni Pisano
|
35 |
+
Giusto de Menabuoi
|
36 |
+
Goro di Gregorio
|
37 |
+
Guariento di Arpo
|
38 |
+
Guido Bigarelli
|
39 |
+
Henning von der Heide
|
40 |
+
Henri Bellechose
|
41 |
+
Hermann Jean and Paul Limbourg
|
42 |
+
Hermen Rode
|
43 |
+
Jacobello Dalle Masegne
|
44 |
+
Jacomart
|
45 |
+
Jacopo Bellini
|
46 |
+
Jacopo del Casentino
|
47 |
+
Jacquemart de Hesdin
|
48 |
+
Jan Goraj
|
49 |
+
Jan Polack
|
50 |
+
Jaume Huguet
|
51 |
+
Jean de Liege
|
52 |
+
Jean Malouel
|
53 |
+
Jean Pucelle
|
54 |
+
Jörg Syrlin the Elder
|
55 |
+
Jörg Syrlin the Younger
|
56 |
+
Lluís Borrassà
|
57 |
+
Lorenzo Maitani
|
58 |
+
Lorenzo Monaco
|
59 |
+
Maestro Esiguo
|
60 |
+
Master of Saint Veronica
|
61 |
+
Master of San Francesco Bardi
|
62 |
+
Master of San Jacopo a Mucciana
|
63 |
+
Master of Schloss
|
64 |
+
Master of the Berswordt Altar
|
65 |
+
Master of the Dominican Effigies
|
66 |
+
Master of the Drapery Studies
|
67 |
+
Master of the Franciscan Crucifixes
|
68 |
+
Master of the Passion of Christ
|
69 |
+
Master of the Rebel Angels
|
70 |
+
Master of the Rinuccini Chapel
|
71 |
+
Mastro Guglielmo
|
72 |
+
Meister Hartmann
|
73 |
+
Melchior Broederlam
|
74 |
+
Michel Erhart
|
75 |
+
Niccolo di Pietro Gerini
|
76 |
+
Nicola Pisano
|
77 |
+
Nicolaus Haberschrack
|
78 |
+
Nicolo da Bologna
|
79 |
+
Niklaus Weckmann
|
80 |
+
Nino Pisano
|
81 |
+
Pere Johan
|
82 |
+
Pere Oller
|
83 |
+
Pere Serra
|
84 |
+
Peter Parler
|
85 |
+
Puccio Capanna
|
86 |
+
Puccio di Simone
|
87 |
+
Segna di Buonaventure
|
88 |
+
Simone Martini
|
89 |
+
Stefano da Verona
|
90 |
+
Taddeo di Bartolo
|
91 |
+
Theodoric of Prague
|
92 |
+
Tino da Camaino
|
93 |
+
Upper Rhenish Master
|
94 |
+
Veit Stoss
|
95 |
+
Vitale da Bologna
|
ex/dynamic-prompts/collections/artists/European Art/medieval/medieval.txt
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
Byzantine
|
2 |
+
__artists/European Art/medieval/romanesque__
|
3 |
+
__artists/European Art/medieval/gothic__
|
ex/dynamic-prompts/collections/artists/European Art/medieval/romanesque.txt
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Arnau Cadell
|
2 |
+
Benedetto Antelami
|
3 |
+
Berlinghiero Berlinghieri
|
4 |
+
Byzantios
|
5 |
+
Calcarius
|
6 |
+
Claricia
|
7 |
+
Dunstan
|
8 |
+
Ende
|
9 |
+
Gislebertus
|
10 |
+
Guda
|
11 |
+
Hegvald
|
12 |
+
Herrad of Landsberg
|
13 |
+
Horder
|
14 |
+
Hugo d'Oignies
|
15 |
+
Lucchese School
|
16 |
+
Majestatis
|
17 |
+
Master Hugo
|
18 |
+
Master Mateo
|
19 |
+
Master of Cabestany
|
20 |
+
Master of Pedret
|
21 |
+
Master of Taüll
|
22 |
+
Master of the Registrum Gregorii
|
23 |
+
Nicholas of Verdun
|
24 |
+
Notker Physicus
|
25 |
+
Othelric
|
26 |
+
Radovan
|
27 |
+
Renier de Huy
|
28 |
+
Roger of Helmarshausen
|
29 |
+
Sigraf
|
30 |
+
Spearhafoc
|
31 |
+
Tove
|
32 |
+
Vgo
|
33 |
+
Wiligelmo
|
ex/dynamic-prompts/collections/artists/European Art/modern/abstract_expressionism/abstract_expressionism.txt
ADDED
@@ -0,0 +1,395 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Abdul Djalil Pirous
|
2 |
+
Adja Yunkers
|
3 |
+
Adolf Bierbrauer
|
4 |
+
Adolph Gottlieb
|
5 |
+
Ad Reinhardt
|
6 |
+
Agnes Martin
|
7 |
+
Ahmad Sadali
|
8 |
+
Albert Alcalay
|
9 |
+
Albert Irvin
|
10 |
+
Albert Kotin
|
11 |
+
Alexander Bogen
|
12 |
+
Alexander Calder
|
13 |
+
Alexander McNeish
|
14 |
+
Alexandre Istrati
|
15 |
+
Alex Salaueu
|
16 |
+
Alfonso A. Ossorio
|
17 |
+
Alfred L. Copley
|
18 |
+
Alfred Leslie
|
19 |
+
Alfred Russell
|
20 |
+
Alfred Russell
|
21 |
+
Al Held
|
22 |
+
Alice Baber
|
23 |
+
Alma Thomas
|
24 |
+
Amanda Snyder
|
25 |
+
Angela Gegg
|
26 |
+
Anna-Eva Bergman
|
27 |
+
Anne Ryan
|
28 |
+
Annick Gendron
|
29 |
+
Anthony Benjamin
|
30 |
+
Arshile Gorky
|
31 |
+
Arthur Sarkissian
|
32 |
+
Ashot Avagyan
|
33 |
+
Aubrey Williams
|
34 |
+
Balcomb Greene
|
35 |
+
Barbara Januszkiewicz
|
36 |
+
Barnett Newman
|
37 |
+
Barrie Cooke
|
38 |
+
Baruj Salinas
|
39 |
+
Batia Grossbard
|
40 |
+
Beauford Delaney
|
41 |
+
Ben Culwell
|
42 |
+
Boris Mirski Gallery
|
43 |
+
Bradley Walker Tomlin
|
44 |
+
Brian Wall
|
45 |
+
Byron McClintock
|
46 |
+
Calvert Coggeshall
|
47 |
+
Captain Beefheart
|
48 |
+
Carle Hessay
|
49 |
+
Charles Alston
|
50 |
+
Charles Cajori
|
51 |
+
Charles Pollock
|
52 |
+
Charles Ragland Bunnell
|
53 |
+
Charles Seliger
|
54 |
+
Charlotte Park
|
55 |
+
Charlotte Park
|
56 |
+
Christine Ay Tjoe
|
57 |
+
Christopher Oywecha
|
58 |
+
Cleve Gray
|
59 |
+
Clyfford Still
|
60 |
+
Conrad Marca-Relli
|
61 |
+
Cora Kelley Ward
|
62 |
+
Corinne Michelle West
|
63 |
+
Cy Twombly
|
64 |
+
Dan Berger
|
65 |
+
David Budd
|
66 |
+
David Geiser
|
67 |
+
David Hare
|
68 |
+
David Hare
|
69 |
+
David Lund
|
70 |
+
David Park
|
71 |
+
David Park
|
72 |
+
David Sawin
|
73 |
+
David Simpson
|
74 |
+
David Simpson
|
75 |
+
David Smith
|
76 |
+
David Smith
|
77 |
+
David Stromeyer
|
78 |
+
Dick Wray
|
79 |
+
Donald P. Olsen
|
80 |
+
Dorothy Dehner
|
81 |
+
Dorothy Heller
|
82 |
+
Dusti Bongé
|
83 |
+
Earle M. Pilgrim
|
84 |
+
Earl Kerkam
|
85 |
+
Ed Clark
|
86 |
+
Edo Murtić
|
87 |
+
Edward Corbett
|
88 |
+
Edward Corbett
|
89 |
+
Edward Dugmore
|
90 |
+
Elaine de Kooning
|
91 |
+
Elaine Hamilton-O'Neal
|
92 |
+
Eleanor Hilowitz
|
93 |
+
Eligio Pichardo
|
94 |
+
Elmer Bischoff
|
95 |
+
Emerson Woelffer
|
96 |
+
Emiko Nakano
|
97 |
+
Emil Schumacher
|
98 |
+
Enrico Donati
|
99 |
+
Ernest Briggs
|
100 |
+
Esteban Vicente
|
101 |
+
Estelle Asmodelle
|
102 |
+
Eugène de Kermadec
|
103 |
+
Evelyn Buff-Segal
|
104 |
+
Evgeny Chubarov
|
105 |
+
Ezio Martinelli
|
106 |
+
Félix Anaut
|
107 |
+
Frances Kornbluth
|
108 |
+
Franck de Las Mercedes
|
109 |
+
Frank Lobdell
|
110 |
+
Franz Kline
|
111 |
+
Fred Mitchell
|
112 |
+
Fred Mitchell
|
113 |
+
Friedel Dzubas
|
114 |
+
Fritz Bultman
|
115 |
+
Fritz Faiss
|
116 |
+
Fuller Potter
|
117 |
+
Gandy Brodie
|
118 |
+
Geoffrey de Groen
|
119 |
+
George Johnson
|
120 |
+
George Johnson
|
121 |
+
George McNeil
|
122 |
+
George McNeil
|
123 |
+
George Morrison
|
124 |
+
George Morrison
|
125 |
+
George Rickey
|
126 |
+
Georges Mathieu
|
127 |
+
George Stillman
|
128 |
+
Georgina Hunt
|
129 |
+
Gerome Kamrowski
|
130 |
+
Giorgio Cavallon
|
131 |
+
Grace Hartigan
|
132 |
+
Gretna Campbell
|
133 |
+
Hale Woodruff
|
134 |
+
Hans Burkhardt
|
135 |
+
Hans Hartung
|
136 |
+
Hans Hofmann
|
137 |
+
Harold Frank
|
138 |
+
Harold Shapinsky
|
139 |
+
Harold Zisla
|
140 |
+
Harry Jackson
|
141 |
+
Harry Jackson
|
142 |
+
Hassel Smith
|
143 |
+
Hedda Sterne
|
144 |
+
Helen Berman
|
145 |
+
Helene Herzbrun
|
146 |
+
Helen Frankenthaler
|
147 |
+
Henrietta Dubrey
|
148 |
+
Herbert Ferber
|
149 |
+
Hollis Jeffcoat
|
150 |
+
Hortense Gordon
|
151 |
+
Hugh Mesibov
|
152 |
+
Ibram Lassaw
|
153 |
+
Ion Țuculescu
|
154 |
+
Isamu Noguchi
|
155 |
+
Jack Boynton
|
156 |
+
Jack Bush
|
157 |
+
Jack Coulter
|
158 |
+
Jack Hooper
|
159 |
+
Jack Hooper
|
160 |
+
Jackson Pollock
|
161 |
+
Jack Tworkov
|
162 |
+
Jack Whitten
|
163 |
+
Jacob Kainen
|
164 |
+
Jacques Grinberg
|
165 |
+
Jacques Hérold
|
166 |
+
Jacques Hurtubise
|
167 |
+
Jacques Hurtubise
|
168 |
+
Jakob Weidemann
|
169 |
+
James Bishop
|
170 |
+
James Brooks
|
171 |
+
James Brooks
|
172 |
+
James Budd Dixon
|
173 |
+
James Clifford
|
174 |
+
James Clifford
|
175 |
+
James Gahagan
|
176 |
+
James Kelly
|
177 |
+
James Kelly
|
178 |
+
James Kelsey
|
179 |
+
James Kelsey
|
180 |
+
James Rosati
|
181 |
+
James Siena
|
182 |
+
James Verbicky
|
183 |
+
Jane Frank
|
184 |
+
Jane Freilicher
|
185 |
+
Janet Sobel
|
186 |
+
Janice Biala
|
187 |
+
Jay Meuser
|
188 |
+
Jean Dubuffet
|
189 |
+
Jean-Paul Riopelle
|
190 |
+
Jeppesen Victor Martin
|
191 |
+
Jérôme Btesh
|
192 |
+
Jimmy Ernst
|
193 |
+
Joan Mitchell
|
194 |
+
Joe Overstreet
|
195 |
+
Joe Stefanelli
|
196 |
+
Joe Stefanelli
|
197 |
+
John Altoon
|
198 |
+
John Chamberlain
|
199 |
+
John Chamberlain
|
200 |
+
John Copnall
|
201 |
+
John Ferren
|
202 |
+
John Harrison Levee
|
203 |
+
John Hultberg
|
204 |
+
John Levee
|
205 |
+
John Opper
|
206 |
+
John von Wicht
|
207 |
+
Jonas Lundh
|
208 |
+
Jon Schueler
|
209 |
+
José María Sicilia
|
210 |
+
Josep Guinovart
|
211 |
+
Joseph Cornell
|
212 |
+
Joseph Glasco
|
213 |
+
Joseph Goto
|
214 |
+
Joseph Pisani
|
215 |
+
Judith Godwin
|
216 |
+
Jules Olitski
|
217 |
+
Julio Rosado del Valle
|
218 |
+
Julius Hatofsky
|
219 |
+
Kathleen Gemberling Adkison
|
220 |
+
Kenneth Noland
|
221 |
+
Kenneth O. Goehring
|
222 |
+
Kenzo Okada
|
223 |
+
Kevin Connor
|
224 |
+
Kevin Connor
|
225 |
+
Kinuko Emi
|
226 |
+
Knox Martin
|
227 |
+
Kwon Jung Ho
|
228 |
+
Lawrence Calcagno
|
229 |
+
Lee Hall
|
230 |
+
Lee Hall
|
231 |
+
Lee Krasner
|
232 |
+
Leo Amino
|
233 |
+
Leonor Antunes
|
234 |
+
Lester Johnson
|
235 |
+
Lester Johnson
|
236 |
+
Lilly Fenichel
|
237 |
+
Linda Lindeberg
|
238 |
+
Lise Gervais
|
239 |
+
Lola Liivat
|
240 |
+
Louise Bourgeois
|
241 |
+
Louise Nevelson
|
242 |
+
Louis Schanker
|
243 |
+
Louis Siegriest
|
244 |
+
Luc Leestemaker
|
245 |
+
Ludwig Merwart
|
246 |
+
Luke Frost
|
247 |
+
Lundy Siegriest
|
248 |
+
Mala Breuer
|
249 |
+
Malcolm Morley
|
250 |
+
Manouchehr Yektai
|
251 |
+
Manoucher Yektai
|
252 |
+
Manuel Chabrera
|
253 |
+
Mark di Suvero
|
254 |
+
Mark Rothko
|
255 |
+
Mark Tobey
|
256 |
+
Marla Olmstead
|
257 |
+
Marlene Tseng Yu
|
258 |
+
Mary Abbott
|
259 |
+
Mary Abbott
|
260 |
+
Mary Callery
|
261 |
+
Matsumi Kanemitsu
|
262 |
+
Max Shertz
|
263 |
+
Melville Price
|
264 |
+
Mercedes Matter
|
265 |
+
Merton Simpson
|
266 |
+
Michael Goldberg
|
267 |
+
Michael Goldberg
|
268 |
+
Michael Loew
|
269 |
+
Michelle Gregor
|
270 |
+
Milton Resnick
|
271 |
+
Minas Avetisyan
|
272 |
+
Mino Argento
|
273 |
+
Minoru Kawabata
|
274 |
+
Miriam Laufer
|
275 |
+
Mochtar Apin
|
276 |
+
Morris Graves
|
277 |
+
Morris Louis
|
278 |
+
Nanno de Groot
|
279 |
+
Natalia Dumitresco
|
280 |
+
Natalie Edgar
|
281 |
+
Nathan Oliveira
|
282 |
+
Natvar Bhavsar
|
283 |
+
Nela Arias-Misson
|
284 |
+
Nicholas Hondrogen
|
285 |
+
Nicholas Marsicano
|
286 |
+
Nicolas Carone
|
287 |
+
Nína Tryggvadóttir
|
288 |
+
Norman Bluhm
|
289 |
+
Norman Lewis
|
290 |
+
Norman Lewis
|
291 |
+
Onyeka Ibe
|
292 |
+
Otto Fried
|
293 |
+
Otto Nebel
|
294 |
+
Painters Eleven
|
295 |
+
Pascal Foucart
|
296 |
+
Pat Passlof
|
297 |
+
Patricia Hermine Sloane
|
298 |
+
Patricio Moreno Toro
|
299 |
+
Paul Burlin
|
300 |
+
Paul-Émile Borduas
|
301 |
+
Paul Giudicelli
|
302 |
+
Paul Horiuchi
|
303 |
+
Paul Jenkins
|
304 |
+
Paul Jenkins
|
305 |
+
Paul Wonner
|
306 |
+
Perle Fine
|
307 |
+
Peter Voulkos
|
308 |
+
Philip Guston
|
309 |
+
Philip Pavia
|
310 |
+
Philippe Pastor
|
311 |
+
Phillip Pavia
|
312 |
+
Phyllis Wiener
|
313 |
+
Piergiorgio Colautti
|
314 |
+
Ralph Rosenborg
|
315 |
+
Raoul Hague
|
316 |
+
Raymond P. Spillenger
|
317 |
+
Ray Parker
|
318 |
+
Reuben Tam
|
319 |
+
Rhea Carmi
|
320 |
+
Richard Diebenkorn
|
321 |
+
Richard Keyes
|
322 |
+
Richard Lippold
|
323 |
+
Richard Mayhew
|
324 |
+
Richard Pousette-Dart
|
325 |
+
Richard Stankiewicz
|
326 |
+
Robert De Niro Sr.
|
327 |
+
Robert De Niro, Sr.
|
328 |
+
Robert Goodnough
|
329 |
+
Robert Motherwell
|
330 |
+
Robert Richenburg
|
331 |
+
Ronan Walsh
|
332 |
+
Ronnie Landfield
|
333 |
+
Rosemarie Beck
|
334 |
+
Roy Newell
|
335 |
+
Ruth Asawa
|
336 |
+
Sam Francis
|
337 |
+
Sam Glankoff
|
338 |
+
Samuel Bookatz
|
339 |
+
Samuel E. Vázquez
|
340 |
+
Sarai Sherman
|
341 |
+
Seong Moy
|
342 |
+
Serge Poliakoff
|
343 |
+
Sergey Bashkirov
|
344 |
+
Seymour Boardman
|
345 |
+
Seymour Fogel
|
346 |
+
Seymour Lipton
|
347 |
+
Silvio Formichetti
|
348 |
+
Simeon Braguin
|
349 |
+
Sonia Gechtoff
|
350 |
+
Sonya Rapoport
|
351 |
+
Srihadi Soedarsono
|
352 |
+
Stanley Twardowicz
|
353 |
+
Stephen Greene
|
354 |
+
Stephen Greene
|
355 |
+
Susan Mohl Powers
|
356 |
+
Sydney Ball
|
357 |
+
Sylvia Lark
|
358 |
+
Taro Yamamoto
|
359 |
+
Taro Yamamoto
|
360 |
+
Terry Frost
|
361 |
+
The Club
|
362 |
+
The Club
|
363 |
+
The Irascibles
|
364 |
+
Theodore Conrath
|
365 |
+
Theodore Odza
|
366 |
+
Theodore Roszak
|
367 |
+
Theodoros Stamos
|
368 |
+
Theophilus Brown
|
369 |
+
Thomas Sills
|
370 |
+
Thornton Willis
|
371 |
+
Todd Williamson
|
372 |
+
Toko Shinoda
|
373 |
+
Tom Boutis
|
374 |
+
Tom Savage
|
375 |
+
Tom Savage
|
376 |
+
Umi Dachlan
|
377 |
+
Vincent Cavallaro
|
378 |
+
Vincent Pepi
|
379 |
+
Virginia Cuppaidge
|
380 |
+
Vivian Springford
|
381 |
+
Walter Darby Bannard
|
382 |
+
Walter Kuhlman
|
383 |
+
Wilhelmina Weber Furlong
|
384 |
+
Willem de Kooning
|
385 |
+
William Baziotes
|
386 |
+
William H. Littlefield
|
387 |
+
William Melton Halsey
|
388 |
+
William Ronald
|
389 |
+
William Scharf
|
390 |
+
William Walton
|
391 |
+
William Walton
|
392 |
+
Windsor Utley
|
393 |
+
Yiannis Maltezos
|
394 |
+
Yuki Katsura
|
395 |
+
Zoe Longfield
|
ex/dynamic-prompts/collections/artists/European Art/modern/american_impressionism.txt
ADDED
@@ -0,0 +1,88 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Abram Molarsky
|
2 |
+
Albert Henry Krehbiel
|
3 |
+
Alson S. Clark
|
4 |
+
Anna Huntington Stanley
|
5 |
+
Arthur Hill Gilbert
|
6 |
+
Carl Eytel
|
7 |
+
Catherine Wiley
|
8 |
+
Charles S. Kaelin
|
9 |
+
Childe Hassam
|
10 |
+
Christian von Schneidau
|
11 |
+
Clara Elsene Peck
|
12 |
+
Clark Voorhees
|
13 |
+
Colin Campbell Cooper
|
14 |
+
Daniel Garber
|
15 |
+
Dennis Miller Bunker
|
16 |
+
Edgar Alwin Payne
|
17 |
+
Edmund Charles Tarbell
|
18 |
+
Edmund Greacen
|
19 |
+
Edward Charles Volkert
|
20 |
+
Edward Francis Rook
|
21 |
+
Edward Henry Potthast
|
22 |
+
Edward Simmons
|
23 |
+
Edward Willis Redfield
|
24 |
+
Frank DuMond
|
25 |
+
Frank Nuderscher
|
26 |
+
Frank Weston Benson
|
27 |
+
Frederick Carl Frieseke
|
28 |
+
Fred Wagner
|
29 |
+
Fritz Poock
|
30 |
+
George Herbert Baker
|
31 |
+
George Loftus Noyes
|
32 |
+
George Sotter
|
33 |
+
George W Dinckel
|
34 |
+
Guy Rose
|
35 |
+
Hayley Lever
|
36 |
+
J. Alden Weir
|
37 |
+
Johann Berthelsen
|
38 |
+
John Elwood Bundy
|
39 |
+
John Henry Twachtman
|
40 |
+
John Joseph Enneking
|
41 |
+
John Leslie Breck
|
42 |
+
John Noble Barlow
|
43 |
+
John Singer Sargent
|
44 |
+
John White Alexander
|
45 |
+
Joseph DeCamp
|
46 |
+
Joseph Kleitsch
|
47 |
+
J. Ottis Adams
|
48 |
+
Julian Onderdonk
|
49 |
+
Laura Muntz Lyall
|
50 |
+
Leonard Ochtman
|
51 |
+
Lilla Cabot Perry
|
52 |
+
Lucy Bacon
|
53 |
+
Marilyn Bendell
|
54 |
+
Marion Wachtel
|
55 |
+
Martha Walter
|
56 |
+
Mary Agnes Yerkes
|
57 |
+
Mary Cassatt
|
58 |
+
Matilda Browne
|
59 |
+
Otto Stark
|
60 |
+
Paul Cornoyer
|
61 |
+
Paul Sawyier
|
62 |
+
Pedro Figari
|
63 |
+
Porfirio Salinas
|
64 |
+
Reynolds Beal
|
65 |
+
Richard Edward Miller
|
66 |
+
Richard Gruelle
|
67 |
+
Robert F. Gault
|
68 |
+
Robert Reid
|
69 |
+
Robertson Kirtland Mygatt
|
70 |
+
Robert Vonnoh
|
71 |
+
Robert William Wood
|
72 |
+
Sueo Serisawa
|
73 |
+
T. C. Steele
|
74 |
+
Theodore Earl Butler
|
75 |
+
Theodore Lukits
|
76 |
+
Theodore Robinson
|
77 |
+
Thomas Dewing
|
78 |
+
Thomas P. Barnett
|
79 |
+
Tim Solliday
|
80 |
+
Van Dearing Perrine
|
81 |
+
Victor Matson
|
82 |
+
Warren Eugene Brandon
|
83 |
+
Willard Metcalf
|
84 |
+
William Langson Lathrop
|
85 |
+
William McGregor Paxton
|
86 |
+
William Merritt Chase
|
87 |
+
William Samuel Horton
|
88 |
+
Wilson Irvine
|
ex/dynamic-prompts/collections/artists/European Art/modern/art_nouveau.txt
ADDED
@@ -0,0 +1,145 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Abel Pann
|
2 |
+
Adolf Michael Boehm
|
3 |
+
Adolfo Hohenstein
|
4 |
+
Adolphe Willette
|
5 |
+
Aladár Körösfői-Kriesch
|
6 |
+
Alexandre Benois
|
7 |
+
Alois Delug
|
8 |
+
Alois Hans Schram
|
9 |
+
Alphonse Mucha
|
10 |
+
Amelia Bauerle
|
11 |
+
Annie French
|
12 |
+
Anselmo Govi
|
13 |
+
Antonio Fabrés
|
14 |
+
Antonio Juez Nieto
|
15 |
+
Archibald Knox (designer)
|
16 |
+
Arnold Lyongrün
|
17 |
+
Arthur Frank Mathews
|
18 |
+
Austin Osman Spare
|
19 |
+
Bela Čikoš Sesija
|
20 |
+
Bronisława Janowska
|
21 |
+
Bror Geijer Göthe
|
22 |
+
Cesare Laurenti (painter)
|
23 |
+
Charles Rennie Mackintosh
|
24 |
+
Clara Weaver Parrish
|
25 |
+
Constant Detré
|
26 |
+
Duilio Cambellotti
|
27 |
+
Edith Soterius von Sachsenheim
|
28 |
+
Edvard Munch
|
29 |
+
Egon Schiele
|
30 |
+
Elenore Abbott
|
31 |
+
Élisabeth Sonrel
|
32 |
+
Eliseu Visconti
|
33 |
+
Emanuel Vidović
|
34 |
+
Emmi Walther
|
35 |
+
Ernst Linck
|
36 |
+
Erwin Puchinger
|
37 |
+
Erwin Stolz
|
38 |
+
Eugen Jettel
|
39 |
+
Fedir Krychevsky
|
40 |
+
Felician Myrbach
|
41 |
+
Fernand Toussaint
|
42 |
+
Fidus
|
43 |
+
Fidushaus
|
44 |
+
Francis Jourdain
|
45 |
+
Franz Stuck
|
46 |
+
Franz von Matsch
|
47 |
+
Friedrich König (painter)
|
48 |
+
Fritz Mackensen
|
49 |
+
Fujishima Takeji
|
50 |
+
Galileo Chini
|
51 |
+
Georges de Feure
|
52 |
+
Gerda Wegener
|
53 |
+
Giorgio Ceragioli (sculptor)
|
54 |
+
Gojmir Anton Kos
|
55 |
+
Gustav Hahn
|
56 |
+
Gustav Klimt
|
57 |
+
Hans Tichy
|
58 |
+
Hans Unger
|
59 |
+
Hede von Trapp
|
60 |
+
Henri Bellery-Desfontaines
|
61 |
+
Henri de Toulouse-Lautrec
|
62 |
+
Henri Thiriet
|
63 |
+
Henry van de Velde
|
64 |
+
Herbert MacNair
|
65 |
+
Ion Theodorescu-Sion
|
66 |
+
Ivan Milev
|
67 |
+
Jaak van Wijck
|
68 |
+
J. A. G. Acke
|
69 |
+
Jane Atché
|
70 |
+
Janis Rozentāls
|
71 |
+
Jan Toorop
|
72 |
+
Jean Crotti
|
73 |
+
Jean de Bosschère
|
74 |
+
Jean Dupas
|
75 |
+
Jean-Edouard de Castella
|
76 |
+
Jean Rouppert
|
77 |
+
Jens Lund
|
78 |
+
Johann Victor Krämer
|
79 |
+
Johan Thorn Prikker
|
80 |
+
John Duncan (painter)
|
81 |
+
Josef Maria Auchentaller
|
82 |
+
Jules Chéret
|
83 |
+
Julius Exter
|
84 |
+
Kamisaka Sekka
|
85 |
+
Karel Vítězslav Mašek
|
86 |
+
Konrad Mägi
|
87 |
+
Konstantin Korovin
|
88 |
+
Konstantin Somov
|
89 |
+
Konstanty Laszczka
|
90 |
+
Lascăr Vorel
|
91 |
+
Léon Bakst
|
92 |
+
Leo Putz
|
93 |
+
Léo Schnug
|
94 |
+
Lucien Lévy-Dhurmer
|
95 |
+
Ludwig Fahrenkrog
|
96 |
+
Ludwig von Hofmann
|
97 |
+
Ludwik Konarzewski
|
98 |
+
Marcel Janco
|
99 |
+
Marcello Dudovich
|
100 |
+
Margaret Macdonald Mackintosh
|
101 |
+
Maria Yakunchikova
|
102 |
+
Martin Battersby
|
103 |
+
Maurice Langaskens
|
104 |
+
Maximilian Liebenwein
|
105 |
+
Max Kurzweil
|
106 |
+
Mihail Simonidi
|
107 |
+
Mikalojus Konstantinas Čiurlionis
|
108 |
+
Mikhail Vrubel
|
109 |
+
Mirko Rački
|
110 |
+
Octavian Smigelschi
|
111 |
+
Olaf Lange
|
112 |
+
Oskar Zwintscher
|
113 |
+
Osmar Schindler
|
114 |
+
Otto Eckmann
|
115 |
+
Prince Eugen, Duke of Närke
|
116 |
+
Raphael Kirchner
|
117 |
+
Robert Burns (artist)
|
118 |
+
Roberto Montenegro
|
119 |
+
Robert Pötzelberger
|
120 |
+
Rudolf Otto von Ottenfeld
|
121 |
+
Sascha Schneider
|
122 |
+
Stefan Filipkiewicz
|
123 |
+
Ștefan Luchian
|
124 |
+
Sydney Long
|
125 |
+
Theo Nieuwenhuis
|
126 |
+
Théophile Steinlen
|
127 |
+
Thomas Theodor Heine
|
128 |
+
Tomislav Krizman
|
129 |
+
Valentin Držkovic
|
130 |
+
Victor Borisov-Musatov
|
131 |
+
Victor Prouvé
|
132 |
+
__vienna_secession__
|
133 |
+
Viktor Oliva
|
134 |
+
Vojtěch Hynais
|
135 |
+
Vojtěch Preissig
|
136 |
+
Wacław Szymanowski
|
137 |
+
Wilhelm Bernatzik
|
138 |
+
Wilhelm Dachauer
|
139 |
+
William Brown Macdougall
|
140 |
+
Wojciech Weiss
|
141 |
+
Xavier Gosé
|
142 |
+
Yelena Polenova
|
143 |
+
Ze'ev Raban
|
144 |
+
__mir_iskusstva__
|
145 |
+
|
ex/dynamic-prompts/collections/artists/European Art/modern/cloisonnism.txt
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
Émile Bernard
|
2 |
+
Paul Sérusiero
|
3 |
+
Louis Anquetin
|
ex/dynamic-prompts/collections/artists/European Art/modern/cobs_art_colony.txt
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Alice Judson
|
2 |
+
Allen Tucker
|
3 |
+
Charles Ebert
|
4 |
+
Dorothy Ochtman
|
5 |
+
Edward Clark Potter
|
6 |
+
Elmer Livingston MacRae
|
7 |
+
Emil Carlsen
|
8 |
+
Ernest Lawson
|
9 |
+
Genjiro Yeto
|
10 |
+
George Wharton Edward
|
11 |
+
Henry Fitch Taylor
|
12 |
+
J. Alden Weir
|
13 |
+
John Henry Twachtman
|
14 |
+
Kerr Eby
|
15 |
+
Leonard Ochtman
|
16 |
+
Mary Robinson Ebert
|
17 |
+
Mina Fitch Ochtman
|
18 |
+
Robert Reid
|
19 |
+
Theodore Robinson
|