Skip to content

Commit 42548f4

Browse files
Reubendfacebook-github-bot
authored andcommitted
Reduced Captum Insights package size (#562)
Summary: This commit reduces the size of Captum Insights by - Replacing the old graphing library with a more lightweight one - In the standalone app, using compression in the Flask server - In the notebook extension, excluding unused dependencies-of-dependencies ![Graph screenshot](https://user-images.githubusercontent.com/13208038/102558400-31c74080-4082-11eb-93b2-9b5c474fa0ae.png) For the standalone app, it reduces the size significantly: ![size comparison](https://user-images.githubusercontent.com/13208038/102558239-de54f280-4081-11eb-9718-24b9174d408b.png) For the notebook extension, there's a similar size reduction of `index.js` from 1090 KB to 449 KB. Testing: I used `titanic.py` to test this change, making sure that the graphs are working as before and that the other functionality is unnafected. Pull Request resolved: #562 Reviewed By: edward-io Differential Revision: D25628623 Pulled By: Reubend fbshipit-source-id: ef8a0d9ec8c7e0df6955b69dd7a96656defc37e8
1 parent 6851f4c commit 42548f4

File tree

11 files changed

+114
-75
lines changed

11 files changed

+114
-75
lines changed

Diff for: .gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -114,3 +114,4 @@ website/static/js/*
114114
!website/static/js/code_block_buttons.js
115115
website/static/_sphinx-sources/
116116
node_modules
117+
captum/insights/attr_vis/widget/static

Diff for: captum/attr/_utils/visualization.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,7 @@ def format_word_importances(words, importances):
514514

515515
def visualize_text(
516516
datarecords: Iterable[VisualizationDataRecord], legend: bool = True
517-
) -> HTML:
517+
) -> "HTML": # In quotes because this type doesn't exist in standalone mode
518518
assert HAS_IPYTHON, (
519519
"IPython must be available to visualize text. "
520520
"Please run 'pip install ipython'."

Diff for: captum/insights/attr_vis/frontend/package.json

+5-3
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,14 @@
1111
"@types/node": "^14.0.13",
1212
"@types/react": "^16.9.38",
1313
"@types/react-dom": "^16.9.8",
14-
"@types/react-plotly.js": "^2.2.4",
1514
"@types/react-tag-autocomplete": "^5.12.0",
1615
"babel-loader": "^8.0.6",
16+
"chart.js": "^2.9.4",
1717
"css-loader": "3.3.0",
1818
"js-levenshtein": "^1.1.6",
19-
"plotly.js-basic-dist-min": "^1.58.2",
2019
"react": "^16.9.0",
20+
"react-chartjs-2": "^2.11.1",
2121
"react-dom": "^16.9.0",
22-
"react-plotly.js": "^2.4.0",
2322
"react-scripts": "3.4.1",
2423
"react-tag-autocomplete": "^5.11.1",
2524
"typescript": "^3.9.5",
@@ -45,5 +44,8 @@
4544
"last 1 firefox version",
4645
"last 1 safari version"
4746
]
47+
},
48+
"devDependencies": {
49+
"@types/chart.js": "^2.9.29"
4850
}
4951
}

Diff for: captum/insights/attr_vis/frontend/src/components/Feature.tsx

+42-29
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { calcHSLFromScore } from "../utils/color";
2+
import { DataPoint } from "../utils/dataPoint";
23
import React from "react";
34
import styles from "../App.module.css";
45
import Tooltip from "./Tooltip";
5-
import Plot from "./Plot";
6+
import { Bar } from "react-chartjs-2";
67
import { FeatureOutput } from "../models/visualizationOutput";
78

89
interface FeatureProps<T> {
@@ -97,35 +98,47 @@ type GeneralFeatureProps = FeatureProps<{
9798
}>;
9899

99100
function GeneralFeature(props: GeneralFeatureProps) {
100-
return (
101-
<Plot
102-
data={[
103-
{
104-
x: props.data.base,
105-
y: props.data.modified,
106-
type: "bar",
107-
marker: {
108-
color: props.data.modified.map(
109-
(v) => (v < 0 ? "#d45c43" : "#80aaff") // red if negative, else blue
110-
),
111-
},
112-
},
113-
]}
114-
config={{
115-
displayModeBar: false,
116-
}}
117-
layout={{
118-
height: 300,
119-
margin: {
120-
t: 20,
121-
pad: 0,
101+
const data = {
102+
labels: props.data.base,
103+
datasets: [
104+
{
105+
barPercentage: 0.5,
106+
data: props.data.modified,
107+
backgroundColor: (dataPoint: DataPoint) => {
108+
if (!dataPoint.dataset || !dataPoint.dataset.data || dataPoint.datasetIndex === undefined) {
109+
return "#d45c43"; // Default to red
110+
}
111+
const yValue = dataPoint.dataset.data[dataPoint.dataIndex as number] || 0;
112+
return yValue < 0 ? "#d45c43" : "#80aaff"; // Red if negative, else blue
122113
},
123-
yaxis: {
124-
fixedrange: true,
125-
showgrid: false,
126-
},
127-
xaxis: {
128-
fixedrange: false,
114+
},
115+
],
116+
};
117+
118+
return (
119+
<Bar
120+
data={data}
121+
width={300}
122+
height={50}
123+
legend={{ display: false }}
124+
options={{
125+
maintainAspectRatio: false,
126+
scales: {
127+
xAxes: [
128+
{
129+
gridLines: {
130+
display: false,
131+
},
132+
},
133+
],
134+
yAxes: [
135+
{
136+
gridLines: {
137+
lineWidth: 0,
138+
zeroLineWidth: 1,
139+
},
140+
},
141+
],
129142
},
130143
}}
131144
/>

Diff for: captum/insights/attr_vis/frontend/src/components/Plot.tsx

-6
This file was deleted.

Diff for: captum/insights/attr_vis/frontend/src/components/plotly.module.d.ts

-1
This file was deleted.
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import * as chartjs from "chart.js";
2+
3+
// Because there's no data point type exported by the
4+
// main type declaration for chart.js, we have our own.
5+
6+
export interface DataPoint {
7+
chart?: object;
8+
dataIndex?: number;
9+
dataset?: chartjs.ChartDataSets;
10+
datasetIndex?: number;
11+
}

Diff for: captum/insights/attr_vis/frontend/widget/webpack.config.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ module.exports = [
5757
resolve: {
5858
modules: ["../node_modules"],
5959
},
60+
externals: ["moment"], // Removes unused dependency-of-dependency
6061
},
6162
{
6263
// Bundle for the notebook containing the custom widget views and models
@@ -82,6 +83,6 @@ module.exports = [
8283
modules: ["../node_modules"],
8384
extensions: extensions,
8485
},
85-
externals: ["@jupyter-widgets/base"],
86+
externals: ["@jupyter-widgets/base", "moment"],
8687
},
8788
];

Diff for: captum/insights/attr_vis/frontend/yarn.lock

+49-33
Original file line numberDiff line numberDiff line change
@@ -1462,16 +1462,18 @@
14621462
dependencies:
14631463
"@babel/types" "^7.3.0"
14641464

1465+
"@types/chart.js@^2.9.29":
1466+
version "2.9.29"
1467+
resolved "https://registry.yarnpkg.com/@types/chart.js/-/chart.js-2.9.29.tgz#73bf7f02387402943f29946012492f10bde7ed43"
1468+
integrity sha512-WOZMitUU3gHDM0oQsCsVivX+oDsIki93szcTmmUPBm39cCvAELBjokjSDVOoA3xiIEbb+jp17z/3S2tIqruwOQ==
1469+
dependencies:
1470+
moment "^2.10.2"
1471+
14651472
"@types/color-name@^1.1.1":
14661473
version "1.1.1"
14671474
resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
14681475
integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==
14691476

1470-
"@types/d3@^3":
1471-
version "3.5.43"
1472-
resolved "https://registry.yarnpkg.com/@types/d3/-/d3-3.5.43.tgz#e9b4992817e0b6c5efaa7d6e5bb2cee4d73eab58"
1473-
integrity sha512-t9ZmXOcpVxywRw86YtIC54g7M9puRh8hFedRvVfHKf5YyOP6pSxA0TvpXpfseXSCInoW4P7bggTrSDiUOs4g5w==
1474-
14751477
"@types/eslint-visitor-keys@^1.0.0":
14761478
version "1.0.0"
14771479
resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d"
@@ -1544,13 +1546,6 @@
15441546
resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0"
15451547
integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==
15461548

1547-
"@types/plotly.js@*":
1548-
version "1.50.13"
1549-
resolved "https://registry.yarnpkg.com/@types/plotly.js/-/plotly.js-1.50.13.tgz#bd56b37f4d849b63659ccb966fc71d7e61415315"
1550-
integrity sha512-uxqsHe7eZa+RtWI0kPcoBHKDTdQ0rqWWDIivwpwFOrpTtjNe9Vwj0Mc6wZdyHUiq02vsSqdAXDbl6noRKKzmkg==
1551-
dependencies:
1552-
"@types/d3" "^3"
1553-
15541549
"@types/prop-types@*":
15551550
version "15.7.3"
15561551
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7"
@@ -1568,14 +1563,6 @@
15681563
dependencies:
15691564
"@types/react" "*"
15701565

1571-
"@types/react-plotly.js@^2.2.4":
1572-
version "2.2.4"
1573-
resolved "https://registry.yarnpkg.com/@types/react-plotly.js/-/react-plotly.js-2.2.4.tgz#360fcfcace64d0ef173cf0c7d67fc2441b39f659"
1574-
integrity sha512-dsvngno7Ar13XoF2eJXM609Msoc5DPboNp8x4NE4L+rsBEEsu16/0b0Fze8REx3fA4HEUk4rcn3uJsx48m2sew==
1575-
dependencies:
1576-
"@types/plotly.js" "*"
1577-
"@types/react" "*"
1578-
15791566
"@types/react-tag-autocomplete@^5.12.0":
15801567
version "5.12.0"
15811568
resolved "https://registry.yarnpkg.com/@types/react-tag-autocomplete/-/react-tag-autocomplete-5.12.0.tgz#bcebefd07abd20ee7a1d9594cf4f2f0297625868"
@@ -2787,6 +2774,29 @@ chardet@^0.7.0:
27872774
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
27882775
integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==
27892776

2777+
chart.js@^2.9.4:
2778+
version "2.9.4"
2779+
resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-2.9.4.tgz#0827f9563faffb2dc5c06562f8eb10337d5b9684"
2780+
integrity sha512-B07aAzxcrikjAPyV+01j7BmOpxtQETxTSlQ26BEYJ+3iUkbNKaOJ/nDbT6JjyqYxseM0ON12COHYdU2cTIjC7A==
2781+
dependencies:
2782+
chartjs-color "^2.1.0"
2783+
moment "^2.10.2"
2784+
2785+
chartjs-color-string@^0.6.0:
2786+
version "0.6.0"
2787+
resolved "https://registry.yarnpkg.com/chartjs-color-string/-/chartjs-color-string-0.6.0.tgz#1df096621c0e70720a64f4135ea171d051402f71"
2788+
integrity sha512-TIB5OKn1hPJvO7JcteW4WY/63v6KwEdt6udfnDE9iCAZgy+V4SrbSxoIbTw/xkUIapjEI4ExGtD0+6D3KyFd7A==
2789+
dependencies:
2790+
color-name "^1.0.0"
2791+
2792+
chartjs-color@^2.1.0:
2793+
version "2.4.1"
2794+
resolved "https://registry.yarnpkg.com/chartjs-color/-/chartjs-color-2.4.1.tgz#6118bba202fe1ea79dd7f7c0f9da93467296c3b0"
2795+
integrity sha512-haqOg1+Yebys/Ts/9bLo/BqUcONQOdr/hoEr2LLTRl6C5LXctUdHxsCYfvQVg5JIxITrfCNUDr4ntqmQk9+/0w==
2796+
dependencies:
2797+
chartjs-color-string "^0.6.0"
2798+
color-convert "^1.9.3"
2799+
27902800
chokidar@^2.1.8:
27912801
version "2.1.8"
27922802
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917"
@@ -2945,7 +2955,7 @@ collection-visit@^1.0.0:
29452955
map-visit "^1.0.0"
29462956
object-visit "^1.0.0"
29472957

2948-
color-convert@^1.9.0, color-convert@^1.9.1:
2958+
color-convert@^1.9.0, color-convert@^1.9.1, color-convert@^1.9.3:
29492959
version "1.9.3"
29502960
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
29512961
integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
@@ -6616,6 +6626,11 @@ lodash.uniq@^4.5.0:
66166626
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
66176627
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
66186628

6629+
lodash@^4.17.19:
6630+
version "4.17.20"
6631+
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52"
6632+
integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==
6633+
66196634
loglevel@^1.6.6:
66206635
version "1.6.7"
66216636
resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.7.tgz#b3e034233188c68b889f5b862415306f565e2c56"
@@ -6924,6 +6939,11 @@ mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@~0.5.1:
69246939
dependencies:
69256940
minimist "^1.2.5"
69266941

6942+
moment@^2.10.2:
6943+
version "2.29.1"
6944+
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3"
6945+
integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==
6946+
69276947
move-concurrently@^1.0.1:
69286948
version "1.0.1"
69296949
resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92"
@@ -7716,11 +7736,6 @@ pkg-up@^2.0.0:
77167736
dependencies:
77177737
find-up "^2.1.0"
77187738

7719-
plotly.js-basic-dist-min@^1.58.2:
7720-
version "1.58.2"
7721-
resolved "https://registry.yarnpkg.com/plotly.js-basic-dist-min/-/plotly.js-basic-dist-min-1.58.2.tgz#7b40228f0e6d46c8936f90a0d876803df68dfe39"
7722-
integrity sha512-Yu84SGV2+bgK7ZVzmr/xUh7d6qucZ5kR/lA9emJs7N+KFmZXn7t69NCMn5YWCNeKdFys/ogdHBT9iG42yBFdPA==
7723-
77247739
pn@^1.1.0:
77257740
version "1.1.0"
77267741
resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb"
@@ -8657,6 +8672,14 @@ react-app-polyfill@^1.0.6:
86578672
regenerator-runtime "^0.13.3"
86588673
whatwg-fetch "^3.0.0"
86598674

8675+
react-chartjs-2@^2.11.1:
8676+
version "2.11.1"
8677+
resolved "https://registry.yarnpkg.com/react-chartjs-2/-/react-chartjs-2-2.11.1.tgz#a78d0df05fc8bc8ffcd4c4ab5b89a25dd2ca3278"
8678+
integrity sha512-G7cNq/n2Bkh/v4vcI+GKx7Q1xwZexKYhOSj2HmrFXlvNeaURWXun6KlOUpEQwi1cv9Tgs4H3kGywDWMrX2kxfA==
8679+
dependencies:
8680+
lodash "^4.17.19"
8681+
prop-types "^15.7.2"
8682+
86608683
react-dev-utils@^10.2.1:
86618684
version "10.2.1"
86628685
resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-10.2.1.tgz#f6de325ae25fa4d546d09df4bb1befdc6dd19c19"
@@ -8707,13 +8730,6 @@ react-is@^16.12.0, react-is@^16.8.1, react-is@^16.8.4:
87078730
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
87088731
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
87098732

8710-
react-plotly.js@^2.4.0:
8711-
version "2.4.0"
8712-
resolved "https://registry.yarnpkg.com/react-plotly.js/-/react-plotly.js-2.4.0.tgz#7a8fd89ffa126daa36a5855890282960e2e4eaf0"
8713-
integrity sha512-BCkxMe8yWqu3nP/hw9A1KCIuoL67WV5/k68SL9yhEkF6UG+pAuIev9Q3cMKtNkQJZhsYFpOmlqrpPjIdUFACOQ==
8714-
dependencies:
8715-
prop-types "^15.7.2"
8716-
87178733
react-scripts@3.4.1:
87188734
version "3.4.1"
87198735
resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-3.4.1.tgz#f551298b5c71985cc491b9acf3c8e8c0ae3ada0a"

Diff for: captum/insights/attr_vis/server.py

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from typing import Optional
88

99
from flask import Flask, jsonify, render_template, request
10+
from flask_compress import Compress
1011
from torch import Tensor
1112

1213
from captum.log import log_usage
@@ -16,6 +17,7 @@
1617
)
1718
visualizer = None
1819
port = None
20+
Compress(app)
1921

2022

2123
def namedtuple_to_dict(obj):

Diff for: setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def report(*args):
5151
pass
5252

5353

54-
INSIGHTS_REQUIRES = ["flask", "ipython", "ipywidgets", "jupyter"]
54+
INSIGHTS_REQUIRES = ["flask", "ipython", "ipywidgets", "jupyter", "flask-compress"]
5555

5656
INSIGHTS_FILE_SUBDIRS = [
5757
"insights/attr_vis/frontend/build",

0 commit comments

Comments
 (0)