Skip to content

Commit

Permalink
Reduced Captum Insights package size (#562)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Reubend authored and vivekmig committed Jan 21, 2021
1 parent a4b601d commit 227dd47
Show file tree
Hide file tree
Showing 11 changed files with 114 additions and 75 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,4 @@ website/static/js/*
!website/static/js/code_block_buttons.js
website/static/_sphinx-sources/
node_modules
captum/insights/attr_vis/widget/static
2 changes: 1 addition & 1 deletion captum/attr/_utils/visualization.py
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,7 @@ def format_word_importances(words, importances):

def visualize_text(
datarecords: Iterable[VisualizationDataRecord], legend: bool = True
) -> HTML:
) -> "HTML": # In quotes because this type doesn't exist in standalone mode
assert HAS_IPYTHON, (
"IPython must be available to visualize text. "
"Please run 'pip install ipython'."
Expand Down
8 changes: 5 additions & 3 deletions captum/insights/attr_vis/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,14 @@
"@types/node": "^14.0.13",
"@types/react": "^16.9.38",
"@types/react-dom": "^16.9.8",
"@types/react-plotly.js": "^2.2.4",
"@types/react-tag-autocomplete": "^5.12.0",
"babel-loader": "^8.0.6",
"chart.js": "^2.9.4",
"css-loader": "3.3.0",
"js-levenshtein": "^1.1.6",
"plotly.js-basic-dist-min": "^1.58.2",
"react": "^16.9.0",
"react-chartjs-2": "^2.11.1",
"react-dom": "^16.9.0",
"react-plotly.js": "^2.4.0",
"react-scripts": "3.4.1",
"react-tag-autocomplete": "^5.11.1",
"typescript": "^3.9.5",
Expand All @@ -45,5 +44,8 @@
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"@types/chart.js": "^2.9.29"
}
}
71 changes: 42 additions & 29 deletions captum/insights/attr_vis/frontend/src/components/Feature.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { calcHSLFromScore } from "../utils/color";
import { DataPoint } from "../utils/dataPoint";
import React from "react";
import styles from "../App.module.css";
import Tooltip from "./Tooltip";
import Plot from "./Plot";
import { Bar } from "react-chartjs-2";
import { FeatureOutput } from "../models/visualizationOutput";

interface FeatureProps<T> {
Expand Down Expand Up @@ -97,35 +98,47 @@ type GeneralFeatureProps = FeatureProps<{
}>;

function GeneralFeature(props: GeneralFeatureProps) {
return (
<Plot
data={[
{
x: props.data.base,
y: props.data.modified,
type: "bar",
marker: {
color: props.data.modified.map(
(v) => (v < 0 ? "#d45c43" : "#80aaff") // red if negative, else blue
),
},
},
]}
config={{
displayModeBar: false,
}}
layout={{
height: 300,
margin: {
t: 20,
pad: 0,
const data = {
labels: props.data.base,
datasets: [
{
barPercentage: 0.5,
data: props.data.modified,
backgroundColor: (dataPoint: DataPoint) => {
if (!dataPoint.dataset || !dataPoint.dataset.data || dataPoint.datasetIndex === undefined) {
return "#d45c43"; // Default to red
}
const yValue = dataPoint.dataset.data[dataPoint.dataIndex as number] || 0;
return yValue < 0 ? "#d45c43" : "#80aaff"; // Red if negative, else blue
},
yaxis: {
fixedrange: true,
showgrid: false,
},
xaxis: {
fixedrange: false,
},
],
};

return (
<Bar
data={data}
width={300}
height={50}
legend={{ display: false }}
options={{
maintainAspectRatio: false,
scales: {
xAxes: [
{
gridLines: {
display: false,
},
},
],
yAxes: [
{
gridLines: {
lineWidth: 0,
zeroLineWidth: 1,
},
},
],
},
}}
/>
Expand Down
6 changes: 0 additions & 6 deletions captum/insights/attr_vis/frontend/src/components/Plot.tsx

This file was deleted.

This file was deleted.

11 changes: 11 additions & 0 deletions captum/insights/attr_vis/frontend/src/utils/dataPoint.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as chartjs from "chart.js";

// Because there's no data point type exported by the
// main type declaration for chart.js, we have our own.

export interface DataPoint {
chart?: object;
dataIndex?: number;
dataset?: chartjs.ChartDataSets;
datasetIndex?: number;
}
3 changes: 2 additions & 1 deletion captum/insights/attr_vis/frontend/widget/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ module.exports = [
resolve: {
modules: ["../node_modules"],
},
externals: ["moment"], // Removes unused dependency-of-dependency
},
{
// Bundle for the notebook containing the custom widget views and models
Expand All @@ -82,6 +83,6 @@ module.exports = [
modules: ["../node_modules"],
extensions: extensions,
},
externals: ["@jupyter-widgets/base"],
externals: ["@jupyter-widgets/base", "moment"],
},
];
82 changes: 49 additions & 33 deletions captum/insights/attr_vis/frontend/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1462,16 +1462,18 @@
dependencies:
"@babel/types" "^7.3.0"

"@types/chart.js@^2.9.29":
version "2.9.29"
resolved "https://registry.yarnpkg.com/@types/chart.js/-/chart.js-2.9.29.tgz#73bf7f02387402943f29946012492f10bde7ed43"
integrity sha512-WOZMitUU3gHDM0oQsCsVivX+oDsIki93szcTmmUPBm39cCvAELBjokjSDVOoA3xiIEbb+jp17z/3S2tIqruwOQ==
dependencies:
moment "^2.10.2"

"@types/color-name@^1.1.1":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==

"@types/d3@^3":
version "3.5.43"
resolved "https://registry.yarnpkg.com/@types/d3/-/d3-3.5.43.tgz#e9b4992817e0b6c5efaa7d6e5bb2cee4d73eab58"
integrity sha512-t9ZmXOcpVxywRw86YtIC54g7M9puRh8hFedRvVfHKf5YyOP6pSxA0TvpXpfseXSCInoW4P7bggTrSDiUOs4g5w==

"@types/eslint-visitor-keys@^1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d"
Expand Down Expand Up @@ -1544,13 +1546,6 @@
resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0"
integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==

"@types/plotly.js@*":
version "1.50.13"
resolved "https://registry.yarnpkg.com/@types/plotly.js/-/plotly.js-1.50.13.tgz#bd56b37f4d849b63659ccb966fc71d7e61415315"
integrity sha512-uxqsHe7eZa+RtWI0kPcoBHKDTdQ0rqWWDIivwpwFOrpTtjNe9Vwj0Mc6wZdyHUiq02vsSqdAXDbl6noRKKzmkg==
dependencies:
"@types/d3" "^3"

"@types/prop-types@*":
version "15.7.3"
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7"
Expand All @@ -1568,14 +1563,6 @@
dependencies:
"@types/react" "*"

"@types/react-plotly.js@^2.2.4":
version "2.2.4"
resolved "https://registry.yarnpkg.com/@types/react-plotly.js/-/react-plotly.js-2.2.4.tgz#360fcfcace64d0ef173cf0c7d67fc2441b39f659"
integrity sha512-dsvngno7Ar13XoF2eJXM609Msoc5DPboNp8x4NE4L+rsBEEsu16/0b0Fze8REx3fA4HEUk4rcn3uJsx48m2sew==
dependencies:
"@types/plotly.js" "*"
"@types/react" "*"

"@types/react-tag-autocomplete@^5.12.0":
version "5.12.0"
resolved "https://registry.yarnpkg.com/@types/react-tag-autocomplete/-/react-tag-autocomplete-5.12.0.tgz#bcebefd07abd20ee7a1d9594cf4f2f0297625868"
Expand Down Expand Up @@ -2787,6 +2774,29 @@ chardet@^0.7.0:
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==

chart.js@^2.9.4:
version "2.9.4"
resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-2.9.4.tgz#0827f9563faffb2dc5c06562f8eb10337d5b9684"
integrity sha512-B07aAzxcrikjAPyV+01j7BmOpxtQETxTSlQ26BEYJ+3iUkbNKaOJ/nDbT6JjyqYxseM0ON12COHYdU2cTIjC7A==
dependencies:
chartjs-color "^2.1.0"
moment "^2.10.2"

chartjs-color-string@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/chartjs-color-string/-/chartjs-color-string-0.6.0.tgz#1df096621c0e70720a64f4135ea171d051402f71"
integrity sha512-TIB5OKn1hPJvO7JcteW4WY/63v6KwEdt6udfnDE9iCAZgy+V4SrbSxoIbTw/xkUIapjEI4ExGtD0+6D3KyFd7A==
dependencies:
color-name "^1.0.0"

chartjs-color@^2.1.0:
version "2.4.1"
resolved "https://registry.yarnpkg.com/chartjs-color/-/chartjs-color-2.4.1.tgz#6118bba202fe1ea79dd7f7c0f9da93467296c3b0"
integrity sha512-haqOg1+Yebys/Ts/9bLo/BqUcONQOdr/hoEr2LLTRl6C5LXctUdHxsCYfvQVg5JIxITrfCNUDr4ntqmQk9+/0w==
dependencies:
chartjs-color-string "^0.6.0"
color-convert "^1.9.3"

chokidar@^2.1.8:
version "2.1.8"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917"
Expand Down Expand Up @@ -2945,7 +2955,7 @@ collection-visit@^1.0.0:
map-visit "^1.0.0"
object-visit "^1.0.0"

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

lodash@^4.17.19:
version "4.17.20"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52"
integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==

loglevel@^1.6.6:
version "1.6.7"
resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.7.tgz#b3e034233188c68b889f5b862415306f565e2c56"
Expand Down Expand Up @@ -6924,6 +6939,11 @@ mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@~0.5.1:
dependencies:
minimist "^1.2.5"

moment@^2.10.2:
version "2.29.1"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3"
integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==

move-concurrently@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92"
Expand Down Expand Up @@ -7716,11 +7736,6 @@ pkg-up@^2.0.0:
dependencies:
find-up "^2.1.0"

plotly.js-basic-dist-min@^1.58.2:
version "1.58.2"
resolved "https://registry.yarnpkg.com/plotly.js-basic-dist-min/-/plotly.js-basic-dist-min-1.58.2.tgz#7b40228f0e6d46c8936f90a0d876803df68dfe39"
integrity sha512-Yu84SGV2+bgK7ZVzmr/xUh7d6qucZ5kR/lA9emJs7N+KFmZXn7t69NCMn5YWCNeKdFys/ogdHBT9iG42yBFdPA==

pn@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb"
Expand Down Expand Up @@ -8657,6 +8672,14 @@ react-app-polyfill@^1.0.6:
regenerator-runtime "^0.13.3"
whatwg-fetch "^3.0.0"

react-chartjs-2@^2.11.1:
version "2.11.1"
resolved "https://registry.yarnpkg.com/react-chartjs-2/-/react-chartjs-2-2.11.1.tgz#a78d0df05fc8bc8ffcd4c4ab5b89a25dd2ca3278"
integrity sha512-G7cNq/n2Bkh/v4vcI+GKx7Q1xwZexKYhOSj2HmrFXlvNeaURWXun6KlOUpEQwi1cv9Tgs4H3kGywDWMrX2kxfA==
dependencies:
lodash "^4.17.19"
prop-types "^15.7.2"

react-dev-utils@^10.2.1:
version "10.2.1"
resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-10.2.1.tgz#f6de325ae25fa4d546d09df4bb1befdc6dd19c19"
Expand Down Expand Up @@ -8707,13 +8730,6 @@ react-is@^16.12.0, react-is@^16.8.1, react-is@^16.8.4:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==

react-plotly.js@^2.4.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/react-plotly.js/-/react-plotly.js-2.4.0.tgz#7a8fd89ffa126daa36a5855890282960e2e4eaf0"
integrity sha512-BCkxMe8yWqu3nP/hw9A1KCIuoL67WV5/k68SL9yhEkF6UG+pAuIev9Q3cMKtNkQJZhsYFpOmlqrpPjIdUFACOQ==
dependencies:
prop-types "^15.7.2"

[email protected]:
version "3.4.1"
resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-3.4.1.tgz#f551298b5c71985cc491b9acf3c8e8c0ae3ada0a"
Expand Down
2 changes: 2 additions & 0 deletions captum/insights/attr_vis/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from typing import Optional

from flask import Flask, jsonify, render_template, request
from flask_compress import Compress
from torch import Tensor

from captum.log import log_usage
Expand All @@ -16,6 +17,7 @@
)
visualizer = None
port = None
Compress(app)


def namedtuple_to_dict(obj):
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def report(*args):
pass


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

INSIGHTS_FILE_SUBDIRS = [
"insights/attr_vis/frontend/build",
Expand Down

0 comments on commit 227dd47

Please sign in to comment.