oobabooga / text-generation-webui

A Gradio web UI for Large Language Models.
GNU Affero General Public License v3.0
40.21k stars 5.27k forks source link

Allow GUI to work without internet #867

Closed TFWol closed 1 year ago

TFWol commented 1 year ago

Description

If you clear the cache and block online parts like fonts.googleapis.com, the UI will be stuck at Loading... indefinitely.

Is it possible to make this more offline friendly?

Edit

@Slins-23 Has a great workaround in the meantime.

Slins-23 commented 1 year ago

The culprits are Google Fonts and/or Cloudflare's Iframe resize scripts, both of which are included by default in Gradio, at: installer_files/env/lib/site-packages/gradio.

I modified some files and it works for me when offline. All you have to do is download, extract, and replace these files installer_files.zip into oobabooga's root directory (the same folder where the executable files and the folder installer_files are located). That should be enough for it to work offline.

Here's a gist containing all of the files that I modified: https://gist.github.com/Slins-23/9863726997a8933f46e5ee7d6eabc014

Filenames with the dash - character indicate folder nesting from root installer_files\env\lib\site-packages\gradio. i.e. templates-cdn-index.html == installer_files/env/lib/site-packages/gradio/ + templates/cdn/index.html

The first file, iframeResizer.contentWindow.min.js, goes into 2 different folders: installer_files/env/lib/site-packages/gradio/templates/cdn/assets/iframeResizer.contentWindow.min.js and installer_files/env/lib/site-packages/gradio/templates/frontend/assets/iframeResizer.contentWindow.min.js.

I just lost my internet connection for half an hour and was wondering the same, so I glossed over the online requests, modified some lines in the Python scripts/HTML and was able to get it working without an internet connection.

Here's what I had to do:

  1. Download iframeResizer source code from Cloudflare

Download https://cdnjs.cloudflare.com/ajax/libs/iframe-resizer/4.3.6/iframeResizer.contentWindow.min.js to installer_files/env/lib/site-packages/gradio/templates/cdn/assets/iframeResizer.contentWindow.min.js

Copy it to installer_files/env/lib/site-packages/gradio/templates/frontend/assets/iframeResizer.contentWindow.min.js

  1. Delete Google Fonts requests and replace remote iframeResizer with local

At files installer_files/env/lib/site-packages/gradio/templates/cdn/index.html, installer_files/env/lib/site-packages/gradio/templates/frontend/index.html, and installer_files/env/lib/site-packages/gradio/templates/frontend/share.html, remove the section that references https://fonts.gstatic.com, and replace <script src="https://cdnjs.cloudflare.com/ajax/libs/iframe-resizer/4.3.1/iframeResizer.contentWindow.min.js"></script> with <script src="./assets/iframeResizer.contentWindow.min.js"></script>.

Also remove <script type="module" crossorigin src="https://gradio.s3-us-west-2.amazonaws.com/3.24.1/assets/index.18ea9dc6.js"></script>, if it's in your file.

  1. Fix Python files (there are quite a few, so watch out because it's error prone)

These reference lines will change whenever you add/remove lines, so read the code to see if it makes sense, before blindly replacing/removing the line. The goal is to remove references to links and Google fonts, so you don't need much knowledge other than basic Python syntax.

@installer_files/env/lib/site-packages/gradio/test_data/blocks_configs.py, line 190, remove both fonts.googleapis.com strings. Do the same at line 476.

@installer_files/env/lib/site-packages/gradio/themes/__init__.py, line 9, in the from gradio.themes.utils.fonts import Font, GoogleFont expression, remove the , GoogleFont part.

@installer_files/env/lib/site-packages/gradio/themes/base.py, line 338 & 346, delete the lines fonts.GoogleFont("Source Sans Pro"), and fonts.GoogleFont("IBM Plex Mono"),, respectively.

@installer_files/env/lib/site-packages/gradio/themes/builder.py

204: Replace main_fonts, main_is_google = [], [] with main_fonts = []

208, 217: Remove the 2 lines with Google in them.

489, 491: Remove + main_is_google and + mono_is_google.

536, 537: Remove both lines.

544, 545: Remove font_is_google and , pad_to_4(font_is_google), then do the same for font_mono_is_google below.

566, 568: Remove both lines.

667: Remove the line or isinstance(base_font, gr.themes.GoogleFont) != theme_font[1].

671: Replace with f"'{font_name}'".

764: Delete main_is_google variable.

782: Delete mono_is_google variable.

809: Replace for main_font, is_google in zip(main_fonts, main_is_google): with for main_font in main_fonts:. Remove if is_google: main_font = gr.themes.GoogleFont(main_font, weights=font_weights). Do the same thing in the for loop below.

856, 857: Replace with list(main_fonts), list(mono_fonts), respectively.

871: Replace the entire _js variable with """(css,fonts) => {}""".

925: Remove this for loop, which loops over main_is_google + mono_is_google.

@installer_files/env/lib/site-packages/gradio/themes/default.py

22, 30: Delete these lines.

@installer_files/env/lib/site-packages/gradio/themes/glass.py

31: Remove this line.

@installer_files/env/lib/site-packages/gradio/themes/monochrome.py

22, 30: Remove these lines.

@installer_files/env/lib/site-packages/gradio/themes/soft.py

22, 30: Remove these lines.

@installer_files/env/lib/site-packages/gradio/themes/utils/fonts.py

13: Replace line with "class": "font",.

22: Replace line with return Font(name).

44: Delete the entire GoogleFont class.

TFWol commented 1 year ago

Sweet! Thanks for the detailed response. I'll be diving into this as soon as I can get a bit of time. This will be super helpful as a starting point when tackling other similar projects that use gradio.

Next will be figuring out how to stop gradio from bloody beaconing to api.gradio.app, despite the telemetry flags used.

TFWol commented 1 year ago

Works great! I went through the changes via WinMerge. That looks like it was very annoying to do. Here's hoping @oobabooga will have this on radar.

pm4user444 commented 1 year ago

I understand what it's doing, but the prior version didn't need to do this. Can you please alter this to not require internet once it's been installed? Thanks

TFWol commented 1 year ago

@pm4user444 You might want to clarify your post a bit. It sounds like you're confusing us for the developer. Maybe reword it to something like 'I have the same problem!'

oobabooga commented 1 year ago

There is an open issue in gradio for this somewhere. There is nothing I can do at the web UI level

Slins-23 commented 1 year ago

@oobabooga You could use a custom version of gradio. You can fork that gradio version, make similar changes to the ones I did (or even just copy and paste the files I attached, if the changes are stable enough), and point to that repo instead of gradio==3.24.1 at text-generation-webui/requirements.txt, by replacing it with git+git://github.com/oobabooga/offline-gradio-fork.git.

oobabooga commented 1 year ago

@Slins-23 you could submit your fixes as a PR to gradio

Slins-23 commented 1 year ago

@oobabooga The problem is that they're more of a workaround than a fix. I didn't really come up with a sensible solution, I just deleted some references in a pretty nasty way, so it might have some ramifications that I don't know. As your repo uses a specific version, and it worked for me and @TFWol, there's at least some stability for this version specifically.

I just mentioned this issue on theirs, maybe they can look more specifically into these changes and workout a long-term solution. By the way, it seems that some previous versions didn't have this issue, so it might be the case that you could also downgrade.

oobabooga commented 1 year ago

I have disabled the use of Google Fonts in this commit, and the web UI seems to work offline now https://github.com/oobabooga/text-generation-webui/commit/649e4017a5646403f86c813a8471286cb5f98da2

@Slins-23 can you check?

Slins-23 commented 1 year ago

@oobabooga It does work fine for me now. Tested with 649e401 and 49aa050.

oobabooga commented 1 year ago

Thanks for the confirmation. Since yesterday I have also blocked the HTTP request that gradio tries to make when it gets imported (see here the fix), so the only remote request left seems to be to

https://cdnjs.cloudflare.com/ajax/libs/iframe-resizer/4.3.1/iframeResizer.contentWindow.min.js

when the web UI loads on the client side. It should be possible to monkey patch this somehow by changing how this line behaves

https://github.com/gradio-app/gradio/blob/main/gradio/routes.py#L235

Slins-23 commented 1 year ago

@oobabooga No problem, nice idea

TFWol commented 1 year ago

Confirmed working on my side too. Thanks for making changes!

Should I go ahead and close out the issue?

oobabooga commented 1 year ago

Let's close this one since the original problem has been solved