Skip to content

Commit

Permalink
chore(search-quality): layout changes
Browse files Browse the repository at this point in the history
  • Loading branch information
kartik-gupta-ij committed Oct 26, 2024
1 parent e0dcaee commit 07958e2
Show file tree
Hide file tree
Showing 5 changed files with 178 additions and 107 deletions.
44 changes: 44 additions & 0 deletions src/components/Collections/SearchQuality/ExplainLog.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
### Example Output:
```json
[18/10/2024, 01:51:38] Point ID 1(1/100) precision@10: 0.8
(search time exact: 30ms, regular: 5ms)
```

### Explanation

This output provides a comparison between:
- **Exact Search** (full kNN)
- **Approximate Search** (using ANN - Approximate Nearest Neighbor)

**precision@10: 0.8**
- Out of the top 10 results returned by the exact search, 8 were also found in the ANN search.

**Search Time Comparison**
- Exact search: 30ms
- ANN search: 5ms (faster but with minor accuracy loss)

---

### Tuning the HNSW Algorithm (Advanced Mode)

- **"hnsw_ef" parameter**: Controls how many neighbors to consider during a search.
- Increasing **hnsw_ef** improves precision but may slow down the search.

---

### Practical Use

The ANN search (with HNSW) is significantly faster (5ms vs. 30ms) but may have slight accuracy trade-offs.
**Tip**: Adjust **hnsw_ef** in advanced mode to balance speed and accuracy.

---

### Additional Tuning Parameters (set in collection configuration)

1. **"m" Parameter**
- Defines the number of edges per node in the graph.
- A higher **m** value improves accuracy but increases memory usage.

2. **"ef_construct" Parameter**
- Sets the number of neighbors considered during index creation.
- Higher values increase precision but lengthen indexing time.
151 changes: 87 additions & 64 deletions src/components/Collections/SearchQuality/SearchQuality.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,13 @@ import { getSnackbarOptions } from '../../Common/utils/snackbarOptions';
import { useClient } from '../../../context/client-context';
import SearchQualityPanel from './SearchQualityPanel';
import { useSnackbar } from 'notistack';
import { Box, Card, CardHeader } from '@mui/material';
import { Box, Card, CardContent, CardHeader, Grid } from '@mui/material';
import { CopyButton } from '../../Common/CopyButton';
import { bigIntJSON } from '../../../common/bigIntJSON';
import EditorCommon from '../../EditorCommon';
import _ from 'lodash';

const explainLog = `Example Output: [18/10/2024, 01:51:38] Point ID 1(1/100) precision@10: 0.8 (search time exact: 30ms, regular: 5ms)
Explanation:
This output compares the performance of an exact search (full kNN) versus an approximate search using ANN (Approximate Nearest Neighbor).
- precision@10: 0.8: Out of the top 10 results returned by the exact search, 8 were also found in the ANN search.
- Search Time: The exact search took 30ms, whereas the ANN search was much faster, taking only 5ms, but with a small loss in accuracy.
Tuning the HNSW Algorithm (Advanced mode):
- "hnsw_ef" parameter: Controls how many neighbors to consider during a search. Increasing "hnsw_ef" improves precision but slows down the search.
Practical Use:
- The ANN search (with HNSW) is significantly faster (5ms compared to 30ms) but slightly less accurate (precision@10: 0.8). You can adjust parameters like "hnsw_ef" in advanced mode to find the right balance between speed and accuracy.
Additional Tuning Parameters (need to be set in collection configuration):
1. "m" Parameter : Defines the number of edges per node in the graph. A higher "m" value improves accuracy but uses more memory.
2. "ef_construct" Parameter: Sets the number of neighbors to consider during index creation. A higher value increases precision but requires more time during indexing.`;
import * as ExplainLog from './ExplainLog.mdx';
import { mdxComponents } from '../../InteractiveTutorial/MdxComponents/MdxComponents';

const SearchQuality = ({ collectionName }) => {
const { enqueueSnackbar, closeSnackbar } = useSnackbar();
Expand All @@ -37,9 +21,7 @@ const SearchQuality = ({ collectionName }) => {
const handleLogUpdate = (newLog) => {
const date = new Date().toLocaleString();
newLog = `[${date}] ${newLog}`;
setLog((prevLog) => {
return newLog + '\n' + prevLog;
});
setLog((prevLog) => newLog + '\n' + prevLog);
};

const clearLogs = () => {
Expand All @@ -49,64 +31,105 @@ const SearchQuality = ({ collectionName }) => {
useEffect(() => {
client
.getCollection(collectionName)
.then((res) => {
setCollection(() => {
return { ...res };
});
})
.then((res) => setCollection({ ...res }))
.catch((err) => {
enqueueSnackbar(err.message, getSnackbarOptions('error', closeSnackbar));
});
}, []);

// Check that collection.config.params.vectors?.size exists and integer
const isNamedVectors = !collection?.config?.params.vectors?.size && _.isObject(collection?.config?.params?.vectors);
let vectors = {};
if (collection) {
vectors = isNamedVectors ? collection?.config?.params?.vectors : { '': collection?.config?.params?.vectors };
}

return (
<>
{collection?.config?.params?.vectors && (
<SearchQualityPanel
collectionName={collectionName}
vectors={vectors}
loggingFoo={handleLogUpdate}
clearLogsFoo={clearLogs}
sx={{ mt: 5 }}
/>
)}
<Grid
container
spacing={2}
sx={{
height: 'calc(100vh - 283px)',
}}
>
<Grid
item
xs={12}
md={7}
sx={{
display: 'flex',
flexDirection: 'column',
height: '100%',
}}
>
{collection?.config?.params?.vectors && (
<SearchQualityPanel
collectionName={collectionName}
vectors={vectors}
loggingFoo={handleLogUpdate}
clearLogsFoo={clearLogs}
sx={{
flexShrink: 0,
}}
/>
)}
<Card
variant="dual"
sx={{
mt: 2,
flex: '1 1 auto',
display: 'flex',
flexDirection: 'column',
overflow: 'hidden',
}}
>
<CardHeader title="What is search quality?" variant="heading" />
<CardContent
sx={{
pl: 2,
flex: '1 1 auto',
overflowY: 'auto',
}}
>
<ExplainLog.default components={mdxComponents} />
</CardContent>
</Card>
</Grid>

<Card varian="dual" sx={{ mt: 5 }}>
<CardHeader
title={log ? 'Report' : 'What is Search Quality?'}
variant="heading"
<Grid item xs={12} md={5} sx={{ height: '100%' }}>
<Card
sx={{
flexGrow: 1,
height: '100%',
}}
action={<CopyButton text={bigIntJSON.stringify(log)} />}
/>
<Box sx={{ pt: 2, pb: 1, pr: 1 }}>
<EditorCommon
language={'custom-language'}
theme={'custom-language-theme'}
value={log || explainLog}
customHeight={'calc(100vh - 660px)'}
options={{
scrollBeyondLastLine: false,
fontSize: 12,
wordWrap: 'on',
minimap: { enabled: false },
automaticLayout: true,
readOnly: true,
mouseWheelZoom: true,
lineNumbers: 'off',
>
<CardHeader title="Report" action={<CopyButton text={bigIntJSON.stringify(log)} />} />
<Box
sx={{
pt: 2,
pb: 1,
pr: 1,
height: 'calc(100% - 60px)',
}}
/>
</Box>
</Card>
</>
>
<EditorCommon
language="custom-language"
paddingBottom={48}
theme="custom-language-theme"
value={log}
options={{
scrollBeyondLastLine: false,
fontSize: 12,
wordWrap: 'on',
minimap: { enabled: false },
automaticLayout: true,
readOnly: true,
mouseWheelZoom: true,
lineNumbers: 'off',
}}
/>
</Box>
</Card>
</Grid>
</Grid>
);
};

Expand Down
81 changes: 42 additions & 39 deletions src/components/Collections/SearchQuality/SearchQualityPanel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ const SearchQualityPanel = ({ collectionName, vectors, loggingFoo, clearLogsFoo,
Math.sqrt(precisions.reduce((x, val) => x + (val - avgPrecision) ** 2, 0) / precisions.length)
);

loggingFoo('Mean precision@' + limit + ' for collection: ' + avgPrecision + ' ± ' + stdDev);
loggingFoo('Mean precision@' + limit + ' for collection: ' + avgPrecision + ' ± ' + stdDev + '\n');

setPrecision((prev) => {
return {
Expand Down Expand Up @@ -275,46 +275,49 @@ const SearchQualityPanel = ({ collectionName, vectors, loggingFoo, clearLogsFoo,
}}
action={<CopyButton text={advancedMod ? code : bigIntJSON.stringify(vectors)} />}
/>

{!advancedMod && (
<Table>
<TableHead>
<TableRow>
<TableCell sx={{ width: '25%' }}>
<Typography variant="subtitle1" fontWeight={600}>
Vector Name
</Typography>
</TableCell>
<TableCell sx={{ width: '25%' }}>
<Typography variant="subtitle1" fontWeight={600}>
Size
</Typography>
</TableCell>
<TableCell sx={{ width: '25%' }}>
<Typography variant="subtitle1" fontWeight={600}>
Distance
</Typography>
</TableCell>
<TableCell sx={{ width: '25%' }}>
<Typography variant="subtitle1" fontWeight={600}>
Precision
</Typography>
</TableCell>
</TableRow>
</TableHead>
<CardContent>
<Table>
<TableHead>
<TableRow>
<TableCell sx={{ width: '25%' }}>
<Typography variant="subtitle1" fontWeight={600}>
Vector Name
</Typography>
</TableCell>
<TableCell sx={{ width: '25%' }}>
<Typography variant="subtitle1" fontWeight={600}>
Size
</Typography>
</TableCell>
<TableCell sx={{ width: '25%' }}>
<Typography variant="subtitle1" fontWeight={600}>
Distance
</Typography>
</TableCell>
<TableCell sx={{ width: '25%' }}>
<Typography variant="subtitle1" fontWeight={600}>
Precision
</Typography>
</TableCell>
</TableRow>
</TableHead>

<TableBody>
{Object.keys(vectors).map((vectorName) => (
<VectorTableRow
vectorObj={vectors[vectorName]}
name={vectorName}
onCheckIndexQuality={() => onCheckIndexQuality({ using: vectorName })}
precision={precision ? precision[vectorName] : null}
key={vectorName}
isInProgress={inProgress}
/>
))}
</TableBody>
</Table>
<TableBody>
{Object.keys(vectors).map((vectorName) => (
<VectorTableRow
vectorObj={vectors[vectorName]}
name={vectorName}
onCheckIndexQuality={() => onCheckIndexQuality({ using: vectorName })}
precision={precision ? precision[vectorName] : null}
key={vectorName}
isInProgress={inProgress}
/>
))}
</TableBody>
</Table>
</CardContent>
)}

{advancedMod && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,11 @@ export const checkIndexPrecision = async (
limit +
': ' +
precision +
' (search time exact: ' +
'\n (search time exact: ' +
exactSearchElapsed +
'ms, regular: ' +
searchElapsed +
'ms)'
'ms)\n'
);

return precision;
Expand Down
5 changes: 3 additions & 2 deletions src/components/EditorCommon/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ window.MonacoEnvironment = {

loader.config({ monaco });

const EditorCommon = ({ beforeMount, customHeight, ...props }) => {
const EditorCommon = ({ beforeMount, customHeight, paddingBottom = 0, ...props }) => {
const monacoRef = useRef(null);
const editorWrapper = useRef(null);
const theme = useTheme();
Expand Down Expand Up @@ -55,7 +55,7 @@ const EditorCommon = ({ beforeMount, customHeight, ...props }) => {
if (customHeight) {
return;
}
setEditorHeight(height - editorWrapper.current?.offsetTop);
setEditorHeight(height - editorWrapper.current?.offsetTop - paddingBottom);
}, [height, editorWrapper]);

return (
Expand All @@ -74,6 +74,7 @@ EditorCommon.propTypes = {
height: PropTypes.string,
beforeMount: PropTypes.func,
customHeight: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
paddingBottom: PropTypes.number,
...Editor.propTypes,
};

Expand Down

0 comments on commit 07958e2

Please sign in to comment.